From ostinelli@REDACTED Wed Aug 4 18:37:39 2021 From: ostinelli@REDACTED (Roberto Ostinelli) Date: Wed, 4 Aug 2021 18:37:39 +0200 Subject: syn feedback Message-ID: All, I'm doing a brief survey on https://github.com/ostinelli/syn usage & desired features, as I'm missing some for my use cases and considering whether I should do a v3 which includes those and others. For instance, here are some feature requests that I've received: - Improved callback mechanisms when processes are registered / unregistered / join / leave, especially in dynamic clusters. - Support for Mixed-Cluster Versioning. - Namespaces (aka scopes)? - Allow the cluster to run nodes without syn (?). I'd welcome any feedback you'd have while I'm going through this design / evaluation process, do not hesitate to reach out to me privately if you'd rather do so. Thank you, r. -------------- next part -------------- An HTML attachment was scrubbed... URL: From oliver.korpilla@REDACTED Wed Aug 4 19:09:15 2021 From: oliver.korpilla@REDACTED (Oliver Korpilla) Date: Wed, 4 Aug 2021 19:09:15 +0200 Subject: syn feedback In-Reply-To: References: Message-ID: <3c323aec-c9b7-919e-587b-09354f578352@gmx.de> Hello, Roberto. We use syn for all our registry needs even after our need to handle splits has gone away due to changing requirements because it's so reliable and easy to use. One feature that my team is missing is the ability to register a process multiple times under different keys. We have been helping ourselves by spawning "forwarders" that register on behalf of our process and die with it. (If this got implemented in the meantime then we've missed it. Our infrastructure requires us to freeze our libraries for long time periods and so whatever version works for us gets used for a long time. We even patch warnings ourselves when we change to a newer elixir version.) Thanks for syn, it really helps our work! Oliver On 04.08.2021 18:37, Roberto Ostinelli wrote: > All, > I'm doing a brief survey on https://github.com/ostinelli/syn > usage & desired features, as I'm > missing some for my use cases and considering whether I should do a v3 > which includes those and others. > > For instance, here are some feature requests that I've received: > > * Improved callback mechanisms when processes are registered / > unregistered / join / leave, especially in dynamic clusters. > * Support for Mixed-Cluster Versioning. > * Namespaces (aka scopes)? > * Allow the cluster to run nodes without syn (?). > > I'd welcome any feedback you'd have while I'm going through this > design / evaluation process, do not hesitate to reach out to me > privately if you'd rather do so. > > Thank you, > r. -- Diese E-Mail wurde von Avast Antivirus-Software auf Viren gepr?ft. https://www.avast.com/antivirus From ostinelli@REDACTED Wed Aug 4 20:19:28 2021 From: ostinelli@REDACTED (Roberto Ostinelli) Date: Wed, 4 Aug 2021 20:19:28 +0200 Subject: syn feedback In-Reply-To: <3c323aec-c9b7-919e-587b-09354f578352@gmx.de> References: <3c323aec-c9b7-919e-587b-09354f578352@gmx.de> Message-ID: > > One feature that my team is missing is the ability to register a process > multiple times under different keys. We have been helping ourselves by > spawning "forwarders" that register on behalf of our process and die > with it. > > (If this got implemented in the meantime then we've missed it. Our > infrastructure requires us to freeze our libraries for long time periods > and so whatever version works for us gets used for a long time. We even > patch warnings ourselves when we change to a newer elixir version.) > Hi Oliver, It looks like you're still using v1, because you can register a process multiple times under different keys in v2. On a side note: you should consider upgrading to v2 given that the mnesia dependency was completely removed as per v2.1, which means that dynamic node membership (dynamic addition / removal of nodes to the cluster) and net splits are handled way better. Thank you for your feedback, r. -------------- next part -------------- An HTML attachment was scrubbed... URL: From oliver.korpilla@REDACTED Wed Aug 4 20:51:31 2021 From: oliver.korpilla@REDACTED (Oliver Korpilla) Date: Wed, 4 Aug 2021 20:51:31 +0200 Subject: syn feedback In-Reply-To: References: <3c323aec-c9b7-919e-587b-09354f578352@gmx.de> Message-ID: <08228b04-ef41-f044-6241-add62382c226@gmx.de> Well then, that's great. Now I have to nag that tools team for new libraries, but that's good! Thanks, Oliver On 04.08.2021 20:19, Roberto Ostinelli wrote: > > One feature that my team is missing is the ability to register a > process > multiple times under different keys. We have been helping ourselves by > spawning "forwarders" that register on behalf of our process and die > with it. > > (If this got implemented in the meantime then we've missed it. Our > infrastructure requires us to freeze our libraries for long time > periods > and so whatever version works for us gets used for a long time. We > even > patch warnings ourselves when we change to a newer elixir version.) > > > Hi Oliver, > It looks like you're still using v1, because you can register a > process multiple times under different keys in v2. > > On a side note: you should consider upgrading to v2 given?that the > mnesia dependency was completely removed as per v2.1, which means that > dynamic node membership (dynamic addition / removal of nodes to the > cluster) and net splits are handled way better. > > Thank you for your feedback, > r. > > -- Diese E-Mail wurde von Avast Antivirus-Software auf Viren gepr?ft. https://www.avast.com/antivirus -------------- next part -------------- An HTML attachment was scrubbed... URL: From icfp.publicity@REDACTED Fri Aug 6 04:51:04 2021 From: icfp.publicity@REDACTED (Sam Tobin-Hochstadt) Date: Thu, 05 Aug 2021 22:51:04 -0400 Subject: Call for Participation: ICFP 2021 Message-ID: <610ca398ca1bd_1ba72e4760@homer.mail> ===================================================================== Call for Participation ICFP 2021 26th ACM SIGPLAN International Conference on Functional Programming and affiliated events August 22 - August 27, 2021 Online http://icfp21.sigplan.org/ Early Registration until August 7! ===================================================================== ICFP provides a forum for researchers and developers to hear about the latest work on the design, implementations, principles, and uses of functional programming. The conference covers the entire spectrum of work, from practice to theory, including its peripheries. This year, the conference will be a virtual event. All activities will take place online. The main conference will take place from August 23-25, 2021 during two time bands. The first band will be 4PM-11PM Seoul time, and will include both technical and social activities. The second band will repeat (with some variation) the technical program and social activities 12 hours later, 3PM-10PM New York, the following day. We?re excited to announce that ICFP 2021 will feature an invited talk from Ravi Chugh of the University of Chicago. Keynote sessions will take place at 10 PM Seoul/9 AM New York. ICFP has officially accepted 35 exciting papers, and (in its second year) there will also be presentations of 4 papers accepted recently to the Journal of Functional Programming. Co-located symposia and workshops will take place the day before and two days immediately after the main conference. Registration is now open. The early registration deadline is August 7th, 2021. Registration is not free, but is significantly lower than usual, including a $10 discounted registration option available to all. Students who are ACM or SIGPLAN members may register for FREE before the early deadline. https://regmaster.com/2021conf/ICFP21/register.php New this year: Attendees will be able to sign-up for the ICFP Mentoring Program (either to be a mentor, receive mentorship or both). * Overview and affiliated events: http://icfp21.sigplan.org/home * Accepted papers: http://icfp21.sigplan.org/track/icfp-2021-papers#event-overview * JFP Talks: https://icfp21.sigplan.org/track/icfp-2021-jfp-talks#event-overview * Registration is available via: https://regmaster.com/2021conf/ICFP21/register.php Early registration ends 8 August, 2021. * Programming contest: https://icfpcontest2021.github.io/ * Student Research Competition: https://icfp21.sigplan.org/track/icfp-2021-Student-Research-Competition * Follow us on Twitter for the latest news: http://twitter.com/icfp_conference This year, there are 10 events co-located with ICFP: * Erlang Workshop (8/26) * Haskell Implementors' Workshop (8/22) * Haskell Symposium (8/26-8/27) * Higher-Order Programming with Effects (8/22) * miniKanren Workshop (8/26) * ML Family Workshop (8/26) * OCaml Workshop (8/27) * Programming Languages Mentoring Workshop (8/22) * Scheme Workshop (8/27) * Type-Driven Development (8/22) ### ICFP Organizers General Chair: Sukyoung Ryu (KAIST, South Korea) Program Chair: Ron Garcia (UBC, Canada) Artifact Evaluation Co-Chairs: Brent Yorgey (Hendrix College, USA) Gabriel Scherer (INRIA Saclay, France) Industrial Relations Chair: Alan Jeffrey (Roblox, USA) Simon Marlow (Facebook, UK) Programming Contest Organizers: Alex Lang and Jasper Van der Jeugt Publicity and Web Chair: Sam Tobin-Hochstadt (Indiana University, USA) Student Research Competition Chair: Anders Miltner (University of Texas, USA) Workshops Co-Chairs: Zoe Paraskevopoulou (Northeastern University, USA) Leonidas Lampropoulos (University of Maryland, USA) Video Co-Chairs: Leif Andersen (Northeastern University, USA) Ben Chung (Northeastern University, USA) Student Volunteer Co-Chairs: Hanneli Tavante (McGill University, Canada) Jaemin Hong (KAIST, South Korea) Lily Bryant (UBC, Canada) Accessibility Co-Chairs: Lindsey Kuper (UCSC, USA) Kathrin Stark (Princeton, USA) From ifl21.publicity@REDACTED Thu Aug 5 22:53:32 2021 From: ifl21.publicity@REDACTED (Pieter Koopman) Date: Thu, 5 Aug 2021 16:53:32 -0400 Subject: IFL'21 Final call for papers Message-ID: ================================================================================ IFL 2021 33rd Symposium on Implementation and Application of Functional Languages venue: online 1 - 3 September 2021 https://ifl21.cs.ru.nl ================================================================================ Note: - We do accept extended abstracts for presentation - Submission is open - Registration is open Scope The goal of the IFL symposia is to bring together researchers actively engaged in the implementation and application of functional and function-based programming languages. IFL 2021 will be a venue for researchers to present and discuss new ideas and concepts, work in progress, and publication-ripe results related to the implementation and application of functional languages and function-based programming. Industrial track and topics of interest This year's edition of IFL explicitly solicits original work concerning *applications* of functional programming in industry and academia. These contributions will be reviewed by experts with an industrial background. Topics of interest to IFL include, but are not limited to: * language concepts * type systems, type checking, type inferencing * compilation techniques * staged compilation * run-time function specialisation * run-time code generation * partial evaluation * (abstract) interpretation * meta-programming * generic programming * automatic program generation * array processing * concurrent/parallel programming * concurrent/parallel program execution * embedded systems * web applications * (embedded) domain-specific languages * security * novel memory management techniques * run-time profiling performance measurements * debugging and tracing * testing and proofing * virtual/abstract machine architectures * validation, verification of functional programs * tools and programming techniques * applications of functional programming in the industry, including ** functional programming techniques for large applications ** successes of the application functional programming ** challenges for functional programming encountered ** any topic related to the application of functional programming that is interesting for the IFL community Post-symposium peer-review Following IFL tradition, IFL 2021 will use a post-symposium review process to produce the formal proceedings. Before the symposium authors submit draft papers. These draft papers will be screened by the program chairs to make sure that they are within the scope of IFL. The draft papers will be made available to all participants at the symposium. Each draft paper is presented by one of the authors at the symposium. After the symposium every presenter is invited to submit a full paper, incorporating feedback from discussions at the symposium. Work submitted to IFL may not be simultaneously submitted to other venues; submissions must adhere to ACM SIGPLAN's republication policy. The program committee will evaluate these submissions according to their correctness, novelty, originality, relevance, significance, and clarity, and will thereby determine whether the paper is accepted or rejected for the formal proceedings. We plan to publish these proceedings in the International Conference Proceedings Series of the ACM Digital Library, as in previous years. Moreover, the proceedings will also be made publicly available as open access. Important dates Submission deadline of draft papers: 17 August 2021 Notification of acceptance for presentation: 19 August 2021 Registration deadline: 30 August 2021 IFL Symposium: 1-3 September 2021 Submission of papers for proceedings: 6 December 2021 Notification of acceptance: 3 February 2022 Camera-ready version: 15 March 2022 Submission details All contributions must be written in English. Papers must use the ACM two columns conference format, which can be found at: http://www.acm.org/publications/proceedings-template . (For LaTeX users, start your document with \documentclass[format=sigconf]{acmart}.) Note that this format has a rather long but limited list of packages that can be used. Please make sure that your document adheres to this list. The submission Web page for IFL21 is https://easychair.org/conferences/?conf=ifl21 . Peter Landin Prize The Peter Landin Prize is awarded to the best paper presented at the symposium every year. The honoured article is selected by the program committee based on the submissions received for the formal review process. The prize carries a cash award equivalent to 150 Euros. Organisation IFL 2021 Chairs: Pieter Koopman and Peter Achten, Radboud University, The Netherlands IFL Publicity chair: Pieter Koopman, Radboud University, The Netherlands PC: Peter Achten (co-chair) - Radboud University, Netherlands Thomas van Binsbergen - University of Amsterdam, Netherlands Edwin Brady - University of St. Andrews, Scotland Laura Castro - University of A Coru?a, Spain Youyou Cong - Tokyo Institute of Technology, Japan Olaf Chitil - University of Kent, England Andy Gill - University of Kansas, USA Clemens Grelck - University of Amsterdam, Netherlands John Hughes - Chalmers University, Sweden Pieter Koopman (co-chair) - Radboud University, Netherlands Cynthia Kop - Radboud University, Netherlands Jay McCarthey - University of Massachussetts Lowell, USA Neil Mitchell - Facebook, England Jan De Muijnck-Hughes - Glasgow University, Scotland Keiko Nakata - SAP Innovation Center Potsdam, Germany Jurri?n Stutterheim - Standard Chartered, Singapore Simon Thompson - University of Kent, England Melinda T?th - E?tvos Lor?nd University, Hungary Phil Trinder - Glasgow University, Scotland Meng Wang - University of Bristol, England Vikt?ria Zs?k - E?tvos Lor?nd University, Hungary Virtual symposium Because of the Covid-19 pandemic, this year IFL 2021 will be an online event, consisting of paper presentations, discussions and virtual social gatherings. Registered participants can take part from anywhere in the world. Registration Please use the link below to register for IFL 2021: https://docs.google.com/forms/d/e/1FAIpQLSdMFjo-GumKjk4i7szs7n4DhWqKt96t8ofIqshfQFrf4jnvsA/viewform?usp=sf_link Thanks to the sponsors and the support of the Radboud university registration is free of charge. [image: beacon] -------------- next part -------------- An HTML attachment was scrubbed... URL: From unix1@REDACTED Fri Aug 6 15:59:55 2021 From: unix1@REDACTED (unix1@REDACTED) Date: Fri, 06 Aug 2021 06:59:55 -0700 Subject: [ANN] rinse is not a search engine Message-ID: Hi, I created rinse [0] as a very simple service to answer specific common questions without having to load the search engine results. It's written in Erlang + cowboy. So far it can do - unit conversions: "convert 70 pounds to kg" - Wikipedia API search (en): "wiki erlang" - dictionaryapi search (en_us): "define gravity" - few other things [1] like: md5, sha, sha2, uuid, timestamp It can be extended via adding to manifests [2] and creating new modules to handle custom commands. It's fully open source, including the code [3] and the infrastructure [4]. The releases, tests and deployment are mostly automated. If you have any suggestions about - features - improving code, infrastructure or deployment - monitoring/observability or thoughts in general, I'd be happy to hear them here or via GitHub issues (or maybe even PRs?). Thank you for your time, Zurab P.S. please be gentle with the service - it's currently running on a very budget instance size. [0] https://rinse.one/ [1] https://rinse.one/commands [2] https://github.com/RinseOne/rinseweb/blob/ e4c3d24f94ccafe7b30129fafb83cc153a2ccaf7/src/rinseweb_manifests.erl [3] https://github.com/RinseOne/rinseweb [4] https://github.com/RinseOne/ansible-playbooks From admin@REDACTED Sun Aug 8 00:12:31 2021 From: admin@REDACTED (Trevor Brown) Date: Sat, 7 Aug 2021 18:12:31 -0400 Subject: dbg function names Message-ID: <5db2ae39-6200-fc43-0c06-40765e9a9df7@stratus3d.com> Hi, I've used the dbg module a fair bit over the years, and I am curious about the names of the functions. Looking at the list of functions, I came up with what I think each function name means: The function names are all acronyms (except for the ones that clearly aren't like `get_tracer/0` and `stop/0`) and stand for the following: * `c` stands for *c*lear * `cn` stands for *c*lear *n*ode * `ctp` stands for *c*lear *t*race *p*attern * `ctpe` stands for *c*lear *t*race *p*attern *e*vent * `ctpg` stands for *c*lear *t*race *p*attern *g*lobal * `ctpl` stands for *c*lear *t*race *p*attern *l*ocal * `dtp` stands for *d*elete *t*race *p*attern (not sure if it's delete, drop, discard, etc...) * `wtp` stands for *w*rite *t*race *p*attern * `rtp` stands for *r*ead *t*race *p*attern * `n` stands for *n*ode * `i` stands for *i*nformation * `p` stands for *p*rocess * `tp` stands for *t*race *p*attern (implicitly global) * `tpl` stands for *t*race *p*attern *l*ocal * `h` stands for *h*elp * `ln` stands for *l*ist *n*odes * `ltp` stands for *l*ist *t*race *p*atterns Can anyone confirm if I am correct here? And if so, reference any docs explaining this? I personally find that understanding the acronyms makes the functions easier to remember, so it's a shame the official docs don't explain this if I am correct. Also, I've always assumed the module name stood for debug, but is that true? I haven't found any docs on that either. Thanks! Trevor From raimo+erlang-questions@REDACTED Mon Aug 9 18:21:00 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Mon, 9 Aug 2021 18:21:00 +0200 Subject: Connecting cluster with different cookies Message-ID: <20210809162100.GA50019@erix.ericsson.se> Hello Community. Regarding a GitHub Issue in progress: https://github.com/erlang/otp/issues/5063, and a corresponding pull request: https://github.com/erlang/otp/pull/5062 There is an apparently rarely known API call erlang:set_cookie(Node, Cookie) that allows you to configure a cookie to use when communicating with a different node. This/these set cookie/s may/should be different from the node's normal (default) cookie, and the functionality exists to make it possible to connect nodes that have different default cookies. The feature is probably rarely used; almost nobody in the OTP group knew that it existed nor how it is supposed to be used. Connecting only nodes with the same cookie seems to be the norm. The question is now, is this an essential feature / how important is this feature? To completely remove this feature would simplify the code, but if that should destroy an important use case; removing would not be an option. The Issue and PR is about how it is supposed to work; if and how it should be fixed. So, what says the Community? How important feature is it to be able to connect nodes with different cookies? Cheers -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From max.lapshin@REDACTED Mon Aug 9 18:34:03 2021 From: max.lapshin@REDACTED (Max Lapshin) Date: Mon, 9 Aug 2021 19:34:03 +0300 Subject: Connecting cluster with different cookies In-Reply-To: <20210809162100.GA50019@erix.ericsson.se> References: <20210809162100.GA50019@erix.ericsson.se> Message-ID: Frankly speaking, it is a bad design today to have single root password from whole cluster. However, erlang interconnect is a so close and intimate connection between nodes, that same cookie may be ok, if there are other security checks before it. From james@REDACTED Mon Aug 9 18:40:32 2021 From: james@REDACTED (James Aimonetti) Date: Mon, 09 Aug 2021 09:40:32 -0700 Subject: Connecting cluster with different cookies In-Reply-To: <20210809162100.GA50019@erix.ericsson.se> References: <20210809162100.GA50019@erix.ericsson.se> Message-ID: <877dguzi4f.fsf@compy64.2600hz.com> Raimo Niskanen writes: > The question is now, is this an essential feature / how > important is this feature? > In the KAZOO project, we support setting different cookies for connecting to our C-node code in the FreeSWITCH project. This has been in place for over 8 years. While I do not think anyone really uses this feature, I also know that with our recent preliminary release of KAZOO 5.0, we've found folks using corners of the software that we did not anticipate. I would not call this an essential feature for our project, personally, but I am also not relishing finding that one cluster which relies on unique cookies for some reason. I've put out a question to our OPS team and our open source forum. If any users require it as part of their operations, I'll forward that along. -- James Aimonetti Lead Systems Architect 2600Hz | http://2600hz.com | UCaaS CPaaS CCaaS tel:415.886.7905 irc:mc_ @ libera.chat #2600hz From phmander@REDACTED Mon Aug 9 19:07:51 2021 From: phmander@REDACTED (Peter-Henry Mander) Date: Mon, 9 Aug 2021 18:07:51 +0100 Subject: Connecting cluster with different cookies In-Reply-To: <877dguzi4f.fsf@compy64.2600hz.com> References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> Message-ID: Hi Raimo, Thanks for asking (-: We've found this erlang:set_cookie/2 function to be very handy in Operations, to be able to launch a remote shell connecting to nodes in a collection of clusters, each with different cookies. E.g. someone has opened a quote in the to_erl shell, leaving the shell "broken" (please, don't snigger...) in the heat of an incident. The use case is hardly critical, but the ability to swap cookies will be missed. Pete. -------------- next part -------------- An HTML attachment was scrubbed... URL: From t@REDACTED Mon Aug 9 21:56:34 2021 From: t@REDACTED (Tristan Sloughter) Date: Mon, 09 Aug 2021 13:56:34 -0600 Subject: Connecting cluster with different cookies In-Reply-To: References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> Message-ID: <45c2095e-5d68-4552-9e3b-afc416f3c332@www.fastmail.com> It is used in `nodetool` and `install_upgrade_escript` in relx. I know I've used it elsewhere too but can't think of where... may have just been toying with creating tools for managing multiple clusters. -------------- next part -------------- An HTML attachment was scrubbed... URL: From s.ledenev@REDACTED Mon Aug 9 22:04:14 2021 From: s.ledenev@REDACTED (Stanislav Ledenev) Date: Mon, 9 Aug 2021 23:04:14 +0300 Subject: Connecting cluster with different cookies In-Reply-To: References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> Message-ID: Just couple of thoughts: Wouldn't the removal of erlang:set_cookie() have a huge impact on one of the cool features of Erlang - dynamic reconfiguration of the running system without stopping it? This function is the only dynamic way of setting a cookie. Two others are static, i.e. through the file and command line parameter. And also for security demanding applications which work within insecure environments erlang:set_cookie() is a very useful function. I.e. read cookie (which changes in time) from a trusted storage and set it without stopping the whole system. ??, 9 ???. 2021 ?. ? 20:08, Peter-Henry Mander : > Hi Raimo, > > Thanks for asking (-: > > We've found this erlang:set_cookie/2 function to be very handy in > Operations, to be able to launch a remote shell connecting to nodes in a > collection of clusters, each with different cookies. E.g. someone has > opened a quote in the to_erl shell, leaving the shell "broken" (please, > don't snigger...) in the heat of an incident. > > The use case is hardly critical, but the ability to swap cookies will be > missed. > > Pete. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lloyd@REDACTED Tue Aug 10 03:12:20 2021 From: lloyd@REDACTED (Lloyd R. prentice) Date: Mon, 09 Aug 2021 21:12:20 -0400 Subject: List a subdirectories in a directory? Message-ID: <139e91ec-b2cb-4662-8903-9044b35c54f1@www.fastmail.com> Hello, .file:list_dir/1 lists all files in a directory. But I need to list all sub-directories. One would think that this would be a routine function., but my aging eyes fail to find any way to do this. Can someone please show me the path forward? Many thanks, LRP -------------- next part -------------- An HTML attachment was scrubbed... URL: From raoknz@REDACTED Tue Aug 10 04:22:35 2021 From: raoknz@REDACTED (Richard O'Keefe) Date: Tue, 10 Aug 2021 14:22:35 +1200 Subject: List a subdirectories in a directory? In-Reply-To: <139e91ec-b2cb-4662-8903-9044b35c54f1@www.fastmail.com> References: <139e91ec-b2cb-4662-8903-9044b35c54f1@www.fastmail.com> Message-ID: Given a directory and a file name, put them together. Then use file:read_file_info/[1,2] to find out whether that names a directory. On Tue, 10 Aug 2021 at 13:13, Lloyd R. prentice wrote: > > Hello, > > .file:list_dir/1 lists all files in a directory. But I need to list all sub-directories. > > One would think that this would be a routine function., but my aging eyes fail to find any way to do this. > > Can someone please show me the path forward? > > Many thanks, > > LRP > > From lukas@REDACTED Tue Aug 10 08:58:03 2021 From: lukas@REDACTED (Lukas Larsson) Date: Tue, 10 Aug 2021 08:58:03 +0200 Subject: dbg function names In-Reply-To: <5db2ae39-6200-fc43-0c06-40765e9a9df7@stratus3d.com> References: <5db2ae39-6200-fc43-0c06-40765e9a9df7@stratus3d.com> Message-ID: Hello! On Sun, Aug 8, 2021 at 8:42 AM Trevor Brown wrote: > Hi, I've used the dbg module a fair bit over the years, and I am curious > about the names of the functions. Looking at the list of functions, I > came up with what I think each function name means: > > The function names are all acronyms (except for the ones that clearly > aren't like `get_tracer/0` and `stop/0`) and stand for the following: > > * `c` stands for *c*lear > I believe that the solitary `c` stands for *c*all. > * `cn` stands for *c*lear *n*ode > * `ctp` stands for *c*lear *t*race *p*attern > * `ctpe` stands for *c*lear *t*race *p*attern *e*vent > * `ctpg` stands for *c*lear *t*race *p*attern *g*lobal > * `ctpl` stands for *c*lear *t*race *p*attern *l*ocal > * `dtp` stands for *d*elete *t*race *p*attern (not sure if it's delete, > drop, discard, etc...) > If you type "dbg:h(dtp)" it prints: dtp() -> ok - Deletes all saved match_spec's. dtp(N) -> ok - Deletes a specific saved match_spec. So it is `delete`, just as you guessed. > * `wtp` stands for *w*rite *t*race *p*attern > * `rtp` stands for *r*ead *t*race *p*attern > * `n` stands for *n*ode > * `i` stands for *i*nformation > * `p` stands for *p*rocess > * `tp` stands for *t*race *p*attern (implicitly global) > * `tpl` stands for *t*race *p*attern *l*ocal > * `h` stands for *h*elp > * `ln` stands for *l*ist *n*odes > * `ltp` stands for *l*ist *t*race *p*atterns > > Can anyone confirm if I am correct here? And if so, reference any docs > explaining this? I personally find that understanding the acronyms makes > the functions easier to remember, so it's a shame the official docs > don't explain this if I am correct. > I use the same words to describe the acronyms as you have done. I believe the person that designed the dbg API has left the Erlang world for the time being, so if we are incorrect we may never know. If you want to create a PR that adds the names that you have proposed into the documentation I think that it could be a good starting point in making the words behind the acronyms official. > Also, I've always assumed the module name stood for debug, but is that > true? I haven't found any docs on that either. > I believe that you are correct, but I do not know for sure. -------------- next part -------------- An HTML attachment was scrubbed... URL: From lukas@REDACTED Tue Aug 10 09:06:59 2021 From: lukas@REDACTED (Lukas Larsson) Date: Tue, 10 Aug 2021 09:06:59 +0200 Subject: Can't see symbols from Erlang NIF library in core file In-Reply-To: References: Message-ID: Hello! Did you manage to figure out how to get symbols for your nif? There should not be anything special that you have to do other than compiling the nif with debug symbols. Could it be the 3rd party C library that does not have symbols? On Tue, Jul 20, 2021 at 7:38 PM Attila Rajmund Nohl wrote: > Hello! > > I'm working on an Erlang wrapper over a 3rd party C library on Ubuntu > Linux on x86, so I'm creating a NIF. Sometimes my code (I think) > crashes, resulting in a core file. Unfortunately the stacktrace is not > really helpful: > > (gdb) bt > #0 0x00007fc22229968a in ?? () > #1 0x0000000060e816d8 in ?? () > #2 0x0000000007cd48b0 in ?? () > #3 0x00007fc228031410 in ?? () > #4 0x00007fc228040b80 in ?? () > #5 0x00007fc228040c50 in ?? () > #6 0x00007fc22223de0b in ?? () > #7 0x0000000000000000 in ?? () > > even though I built my NIF .so file with debug info: > > ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically > linked, BuildID[sha1]=b70dd1f2450f5c0e9980c8396aaad2e1cd29024c, with > debug_info, not stripped > > The beam binary also has debug info: > > ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically > linked, interpreter /lib64/ld-linux-x86-64.so.2, > BuildID[sha1]=e0a5dba6507b8c2b333faebc89fbc6ea2f7263b9, for GNU/Linux > 3.2.0, with debug_info, not stripped > > However, info sharedlibrary doesn't show neither the NIF nor the 3rd party > lib: > > (gdb) info sharedlibrary > From To Syms Read Shared Object Library > 0x00007fc28942ed50 0x00007fc289432004 Yes > /lib/x86_64-linux-gnu/libgtk3-nocsd.so.0 > 0x00007fc289429220 0x00007fc28942a179 Yes > /lib/x86_64-linux-gnu/libdl.so.2 > 0x00007fc2892e83c0 0x00007fc28938ef18 Yes > /lib/x86_64-linux-gnu/libm.so.6 > 0x00007fc2892b76a0 0x00007fc2892c517c Yes > /lib/x86_64-linux-gnu/libtinfo.so.6 > 0x00007fc28928dae0 0x00007fc28929d4d5 Yes > /lib/x86_64-linux-gnu/libpthread.so.0 > 0x00007fc2890b9630 0x00007fc28922e20d Yes > /lib/x86_64-linux-gnu/libc.so.6 > 0x00007fc289657100 0x00007fc289679674 Yes (*) > /lib64/ld-linux-x86-64.so.2 > 0x00007fc24459c040 0x00007fc2445ab8ad Yes > /home/nar/otp/23.3.4.2/lib/crypto-4.9.0.2/priv/lib/crypto.so > 0x00007fc2239e3000 0x00007fc223b7c800 Yes (*) > /lib/x86_64-linux-gnu/libcrypto.so.1.1 > 0x00007fc2896500e0 0x00007fc28965028c Yes > /home/nar/otp/23.3.4.2/lib/crypto-4.9.0.2/priv/lib/crypto_callback.so > 0x00007fc289649380 > > 0x00007fc28964bc1c Yes > /home/nar/otp/23.3.4.2/lib/asn1-5.0.15/priv/lib/asn1rt_nif.so > 0x00007fc289638720 0x00007fc28963bd70 Yes > /lib/x86_64-linux-gnu/librt.so.1 > The asn1rt_nif.so and crypto.so nifs have no special treatment and are loaded in exactly the same way as a user-defined nif. So there is most likely something different/wrong with how your nif is compiled and/or loaded. > > I found an answer at stackoverflow > (https://stackoverflow.com/a/32727752/2414208) mentioning that "The > Erlang VM doesn't load NIF libraries with global symbols exposed". > Could this be the reason why I don't see the symbols? Is there a way > to tell gdb to look up symbols from my .so file? > I don't think the stackoverflow question is related to your problem as it seems to be related to symbols not resolving when doing dlopen and not when using gdb. -------------- next part -------------- An HTML attachment was scrubbed... URL: From msheldon@REDACTED Mon Aug 9 19:29:15 2021 From: msheldon@REDACTED (Mark Sheldon) Date: Mon, 9 Aug 2021 13:29:15 -0400 Subject: Connecting cluster with different cookies In-Reply-To: <877dguzi4f.fsf@compy64.2600hz.com> References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> Message-ID: I don?t represent a large application, but perhaps this is a common use case ? or perhaps someone can give me a better way to do this. I use erlang:set_cookie/2 in escripts I have my students (and potentially teaching assistants) use to communicate with Erlang services I provide. For example, I have a script for submitting late work that captures dates on students files and sends the student?s submission and metadata to an Erlang server. These programs are run by students whose accounts I cannot control. They are not in any privileged Unix group, and they will not have a cookie file in their home directories. So, the scripts explicitly set the cookie so that they can communicate with my server(s). An analogous situation could arise if I want to have a web page interact with a service. The department uses Apache and supports CGI scripts. I can write an escripts in the same way as above. I don?t run that many services, but it seems reasonable to have services available to staff that are different from students and to use different cookies for the two groups of nodes. I understand that it?s not great security. But the scripts can only be run people with department accounts, and the network is behind a firewall. If I have missed a better solution, I?d be interested to hear about it. I mostly hacked the late submission system together one afternoon as a more fun approach to a common problem, and I?ve been using it ever since. -Mark Mark A. Sheldon Associate Teaching Professor Department of Computer Science Tufts University > On 9Aug, 2021, at 12:40, James Aimonetti wrote: > > > Raimo Niskanen writes: > >> The question is now, is this an essential feature / how >> important is this feature? >> > > In the KAZOO project, we support setting different cookies for > connecting to our C-node code in the FreeSWITCH project. This has been > in place for over 8 years. > > While I do not think anyone really uses this feature, I also know that > with our recent preliminary release of KAZOO 5.0, we've found folks > using corners of the software that we did not anticipate. > > I would not call this an essential feature for our project, personally, > but I am also not relishing finding that one cluster which relies on > unique cookies for some reason. > > I've put out a question to our OPS team and our open source forum. If > any users require it as part of their operations, I'll forward that > along. > > -- > James Aimonetti > > Lead Systems Architect > 2600Hz | http://2600hz.com | UCaaS CPaaS CCaaS > tel:415.886.7905 > irc:mc_ @ libera.chat #2600hz -------------- next part -------------- An HTML attachment was scrubbed... URL: From raimo+erlang-questions@REDACTED Tue Aug 10 10:52:00 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Tue, 10 Aug 2021 10:52:00 +0200 Subject: Connecting cluster with different cookies In-Reply-To: <20210809162100.GA50019@erix.ericsson.se> References: <20210809162100.GA50019@erix.ericsson.se> Message-ID: <20210810085200.GA21612@erix.ericsson.se> To clarify; we are not talking about deleting the possibility to set the default cookie for the node through an API function, although today the only way to do that is by calling erlang:set_cookie(node(), Cookie). An obvious erlang:set_cookie(Cookie) is missing and could be added. It is setting differing cookies for other nodes that is the feature scrutinized here i.e erlang:set_cookie(OtherNode, OtherCookie). All your use cases; can they be solved by setting the default cookie for the node? E.g starting a node to just to interact with a cluster, is it needed/desirable to be able to interact with several clusters simultaneously, or do you start a dedicated node for that interaction, hence would it be possible to just set the default cookie for the interaction node during the interaction? Cheers / Raimo Niskanen On Mon, Aug 09, 2021 at 06:21:00PM +0200, Raimo Niskanen wrote: > Hello Community. > > Regarding a GitHub Issue in progress: > https://github.com/erlang/otp/issues/5063, > and a corresponding pull request: > https://github.com/erlang/otp/pull/5062 > > There is an apparently rarely known API call > erlang:set_cookie(Node, Cookie) that allows you to configure > a cookie to use when communicating with a different node. > > This/these set cookie/s may/should be different from the node's > normal (default) cookie, and the functionality exists > to make it possible to connect nodes that have different > default cookies. > > The feature is probably rarely used; almost nobody in the > OTP group knew that it existed nor how it is supposed > to be used. Connecting only nodes with the same cookie > seems to be the norm. > > The question is now, is this an essential feature / how > important is this feature? > > To completely remove this feature would simplify the code, > but if that should destroy an important use case; removing > would not be an option. > > The Issue and PR is about how it is supposed to work; if and > how it should be fixed. > > > So, what says the Community? How important feature is it > to be able to connect nodes with different cookies? > > Cheers > -- > > / Raimo Niskanen, Erlang/OTP, Ericsson AB -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From raimo+erlang-questions@REDACTED Tue Aug 10 10:54:36 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Tue, 10 Aug 2021 10:54:36 +0200 Subject: Connecting cluster with different cookies In-Reply-To: <22E2E24C-7572-433F-8200-C4F3182E86E7@niemier.pl> References: <20210809162100.GA50019@erix.ericsson.se> <22E2E24C-7572-433F-8200-C4F3182E86E7@niemier.pl> Message-ID: <20210810085436.GB21612@erix.ericsson.se> On Mon, Aug 09, 2021 at 06:34:02PM +0200, ?ukasz Niemier wrote: > > So, what says the Community? How important feature is it > > to be able to connect nodes with different cookies? > > I never had need for that, but I think that it could have some uses in the past when there was no TLS connection and cookie was only "protection". Nowadays it is IMHO pointless and serves only as a way to prevent accidental connections to different cluster. In that form cookie at all is loosing it's raison d'?tre. I think, that unless there is any large player that extensively is using this feature and is willing to provide resources for maintenance of such, then we should drop it. > > I would even say, that maybe we should consider dropping the cookies in general, and instead move such feature to another layer like mutual TLS? I think non-encrypted distribution over a safe network still has its use, and that the cookies in this case as you say helps protect against accidental connections to the wrong cluster. > > -- > > ?ukasz Niemier > lukasz@REDACTED > -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From raimo+erlang-questions@REDACTED Tue Aug 10 10:56:37 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Tue, 10 Aug 2021 10:56:37 +0200 Subject: Connecting cluster with different cookies In-Reply-To: <877dguzi4f.fsf@compy64.2600hz.com> References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> Message-ID: <20210810085636.GC21612@erix.ericsson.se> Would it be sufficient to be able to set the default cookie for a node with e.g a new API function erlang:set_cookie(Cookie)? / Raimo Niskanen On Mon, Aug 09, 2021 at 09:40:32AM -0700, James Aimonetti wrote: > > Raimo Niskanen writes: > > > The question is now, is this an essential feature / how > > important is this feature? > > > > In the KAZOO project, we support setting different cookies for > connecting to our C-node code in the FreeSWITCH project. This has been > in place for over 8 years. > > While I do not think anyone really uses this feature, I also know that > with our recent preliminary release of KAZOO 5.0, we've found folks > using corners of the software that we did not anticipate. > > I would not call this an essential feature for our project, personally, > but I am also not relishing finding that one cluster which relies on > unique cookies for some reason. > > I've put out a question to our OPS team and our open source forum. If > any users require it as part of their operations, I'll forward that > along. > > -- > James Aimonetti > > Lead Systems Architect > 2600Hz | http://2600hz.com | UCaaS CPaaS CCaaS > tel:415.886.7905 > irc:mc_ @ libera.chat #2600hz -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From raimo+erlang-questions@REDACTED Tue Aug 10 10:57:00 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Tue, 10 Aug 2021 10:57:00 +0200 Subject: Connecting cluster with different cookies In-Reply-To: References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> Message-ID: <20210810085659.GD21612@erix.ericsson.se> Would it be sufficient to be able to set the default cookie for a node with e.g a new API function erlang:set_cookie(Cookie)? / Raimo Niskanen On Mon, Aug 09, 2021 at 01:29:15PM -0400, Mark Sheldon wrote: > I don?t represent a large application, but perhaps this is a common use case ? or perhaps someone can give me a better way to do this. > > I use erlang:set_cookie/2 in escripts I have my students (and potentially teaching assistants) use to communicate with Erlang services I provide. For example, I have a script for submitting late work that captures dates on students files and sends the student?s submission and metadata to an Erlang server. > > These programs are run by students whose accounts I cannot control. They are not in any privileged Unix group, and they will not have a cookie file in their home directories. So, the scripts explicitly set the cookie so that they can communicate with my server(s). > > An analogous situation could arise if I want to have a web page interact with a service. The department uses Apache and supports CGI scripts. I can write an escripts in the same way as above. > > I don?t run that many services, but it seems reasonable to have services available to staff that are different from students and to use different cookies for the two groups of nodes. > > I understand that it?s not great security. But the scripts can only be run people with department accounts, and the network is behind a firewall. > > If I have missed a better solution, I?d be interested to hear about it. I mostly hacked the late submission system together one afternoon as a more fun approach to a common problem, and I?ve been using it ever since. > > -Mark > > > Mark A. Sheldon > Associate Teaching Professor > Department of Computer Science > Tufts University > > > > On 9Aug, 2021, at 12:40, James Aimonetti wrote: > > > > > > Raimo Niskanen writes: > > > >> The question is now, is this an essential feature / how > >> important is this feature? > >> > > > > In the KAZOO project, we support setting different cookies for > > connecting to our C-node code in the FreeSWITCH project. This has been > > in place for over 8 years. > > > > While I do not think anyone really uses this feature, I also know that > > with our recent preliminary release of KAZOO 5.0, we've found folks > > using corners of the software that we did not anticipate. > > > > I would not call this an essential feature for our project, personally, > > but I am also not relishing finding that one cluster which relies on > > unique cookies for some reason. > > > > I've put out a question to our OPS team and our open source forum. If > > any users require it as part of their operations, I'll forward that > > along. > > > > -- > > James Aimonetti > > > > Lead Systems Architect > > 2600Hz | http://2600hz.com | UCaaS CPaaS CCaaS > > tel:415.886.7905 > > irc:mc_ @ libera.chat #2600hz > -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From raimo+erlang-questions@REDACTED Tue Aug 10 10:57:22 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Tue, 10 Aug 2021 10:57:22 +0200 Subject: Connecting cluster with different cookies In-Reply-To: References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> Message-ID: <20210810085722.GE21612@erix.ericsson.se> Would it be sufficient to be able to set the default cookie for a node with e.g a new API function erlang:set_cookie(Cookie)? / Raimo Niskanen On Mon, Aug 09, 2021 at 06:07:51PM +0100, Peter-Henry Mander wrote: > Hi Raimo, > > Thanks for asking (-: > > We've found this erlang:set_cookie/2 function to be very handy in > Operations, to be able to launch a remote shell connecting to nodes in a > collection of clusters, each with different cookies. E.g. someone has > opened a quote in the to_erl shell, leaving the shell "broken" (please, > don't snigger...) in the heat of an incident. > > The use case is hardly critical, but the ability to swap cookies will be > missed. > > Pete. -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From raimo+erlang-questions@REDACTED Tue Aug 10 10:57:46 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Tue, 10 Aug 2021 10:57:46 +0200 Subject: Connecting cluster with different cookies In-Reply-To: <45c2095e-5d68-4552-9e3b-afc416f3c332@www.fastmail.com> References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> <45c2095e-5d68-4552-9e3b-afc416f3c332@www.fastmail.com> Message-ID: <20210810085746.GF21612@erix.ericsson.se> Would it be sufficient to be able to set the default cookie for a node with e.g a new API function erlang:set_cookie(Cookie)? / Raimo Niskanen On Mon, Aug 09, 2021 at 01:56:34PM -0600, Tristan Sloughter wrote: > It is used in `nodetool` and `install_upgrade_escript` in relx. > > I know I've used it elsewhere too but can't think of where... may have just been toying with creating tools for managing multiple clusters. -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From raimo+erlang-questions@REDACTED Tue Aug 10 10:58:09 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Tue, 10 Aug 2021 10:58:09 +0200 Subject: Connecting cluster with different cookies In-Reply-To: References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> Message-ID: <20210810085809.GG21612@erix.ericsson.se> Would it be sufficient to be able to set the default cookie for a node with e.g a new API function erlang:set_cookie(Cookie)? / Raimo Niskanen On Mon, Aug 09, 2021 at 11:04:14PM +0300, Stanislav Ledenev wrote: > Just couple of thoughts: > > Wouldn't the removal of erlang:set_cookie() have a huge impact on one of > the cool > features of Erlang - dynamic reconfiguration of the running system without > stopping it? > This function is the only dynamic way of setting a cookie. Two others are > static, i.e. > through the file and command line parameter. > > And also for security demanding applications which work within insecure > environments erlang:set_cookie() is a very useful function. I.e. read cookie > (which changes in time) from a trusted storage and set it without stopping > the > whole system. > > ??, 9 ???. 2021 ?. ? 20:08, Peter-Henry Mander : > > > Hi Raimo, > > > > Thanks for asking (-: > > > > We've found this erlang:set_cookie/2 function to be very handy in > > Operations, to be able to launch a remote shell connecting to nodes in a > > collection of clusters, each with different cookies. E.g. someone has > > opened a quote in the to_erl shell, leaving the shell "broken" (please, > > don't snigger...) in the heat of an incident. > > > > The use case is hardly critical, but the ability to swap cookies will be > > missed. > > > > Pete. > > > > -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From stavros.aronis@REDACTED Tue Aug 10 10:54:34 2021 From: stavros.aronis@REDACTED (Stavros Aronis) Date: Tue, 10 Aug 2021 08:54:34 +0000 Subject: Call for Participation: ICFP 2021 In-Reply-To: <610ca398ca1bd_1ba72e4760@homer.mail> References: <610ca398ca1bd_1ba72e4760@homer.mail> Message-ID: Hi! Worth noting here as well, that thanks to Erlang Solutions and the Erlang Ecosystem Foundation, the Erlang Workshop at ICFP 2021 offers Diversity & Inclusion Scholarships for people who would otherwise not be able to attend. Read more here: https://icfp21.sigplan.org/home/erlang-2021#Diversity-Inclusion-Scholarships Looking forward to seeing some of you there! Best Regards, Stavros ??????? Original Message ??????? On Friday, August 6th, 2021 at 4:51 AM, Sam Tobin-Hochstadt wrote: > ===================================================================== > > Call for Participation > > ICFP 2021 > > 26th ACM SIGPLAN International Conference on Functional Programming > > and affiliated events > > August 22 - August 27, 2021 > > Online > > http://icfp21.sigplan.org/ > > Early Registration until August 7! > > ============================================================================================================================================================================================================================================================================================================ > > ICFP provides a forum for researchers and developers to hear > > about the latest work on the design, implementations, principles, and > > uses of functional programming. The conference covers the entire > > spectrum of work, from practice to theory, including its peripheries. > > This year, the conference will be a virtual event. All activities will > > take place online. > > The main conference will take place from August 23-25, 2021 during two > > time bands. The first band will be 4PM-11PM Seoul time, and will > > include both technical and social activities. The second band will > > repeat (with some variation) the technical program and social > > activities 12 hours later, 3PM-10PM New York, the following day. > > We?re excited to announce that ICFP 2021 will feature an invited talk > > from Ravi Chugh of the University of Chicago. Keynote sessions will > > take place at 10 PM Seoul/9 AM New York. > > ICFP has officially accepted 35 exciting papers, and (in its second > > year) there will also be presentations of 4 papers accepted recently > > to the Journal of Functional Programming. Co-located symposia and > > workshops will take place the day before and two days immediately > > after the main conference. > > Registration is now open. The early registration deadline is August > > 7th, 2021. Registration is not free, but is significantly lower than > > usual, including a $10 discounted registration option available to > > all. Students who are ACM or SIGPLAN members may register for FREE > > before the early deadline. > > https://regmaster.com/2021conf/ICFP21/register.php > > New this year: Attendees will be able to sign-up for the ICFP > > Mentoring Program (either to be a mentor, receive mentorship or both). > > - Overview and affiliated events: > > http://icfp21.sigplan.org/home > - Accepted papers: > > http://icfp21.sigplan.org/track/icfp-2021-papers#event-overview > - JFP Talks: > > https://icfp21.sigplan.org/track/icfp-2021-jfp-talks#event-overview > - Registration is available via: > > https://regmaster.com/2021conf/ICFP21/register.php > > Early registration ends 8 August, 2021. > - Programming contest: > > https://icfpcontest2021.github.io/ > - Student Research Competition: > > https://icfp21.sigplan.org/track/icfp-2021-Student-Research-Competition > - Follow us on Twitter for the latest news: > > http://twitter.com/icfp_conference > > This year, there are 10 events co-located with ICFP: > - Erlang Workshop (8/26) > - Haskell Implementors' Workshop (8/22) > - Haskell Symposium (8/26-8/27) > - Higher-Order Programming with Effects (8/22) > - miniKanren Workshop (8/26) > - ML Family Workshop (8/26) > - OCaml Workshop (8/27) > - Programming Languages Mentoring Workshop (8/22) > - Scheme Workshop (8/27) > - Type-Driven Development (8/22) > > ### ICFP Organizers > > General Chair: Sukyoung Ryu (KAIST, South Korea) > > Program Chair: Ron Garcia (UBC, Canada) > > Artifact Evaluation Co-Chairs: Brent Yorgey (Hendrix College, USA) > > Gabriel Scherer (INRIA Saclay, France) > > Industrial Relations Chair: Alan Jeffrey (Roblox, USA) > > Simon Marlow (Facebook, UK) > > Programming Contest Organizers: Alex Lang and Jasper Van der Jeugt > > Publicity and Web Chair: Sam Tobin-Hochstadt (Indiana University, USA) > > Student Research Competition Chair: Anders Miltner (University of Texas, USA) > > Workshops Co-Chairs: Zoe Paraskevopoulou (Northeastern University, USA) > > Leonidas Lampropoulos (University of Maryland, USA) > > Video Co-Chairs: Leif Andersen (Northeastern University, USA) > > Ben Chung (Northeastern University, USA) > > Student Volunteer Co-Chairs: Hanneli Tavante (McGill University, Canada) > > Jaemin Hong (KAIST, South Korea) > > Lily Bryant (UBC, Canada) > > Accessibility Co-Chairs: Lindsey Kuper (UCSC, USA) > > Kathrin Stark (Princeton, USA) From roger@REDACTED Tue Aug 10 11:04:21 2021 From: roger@REDACTED (Roger Lipscombe) Date: Tue, 10 Aug 2021 10:04:21 +0100 Subject: Connecting cluster with different cookies In-Reply-To: <20210809162100.GA50019@erix.ericsson.se> References: <20210809162100.GA50019@erix.ericsson.se> Message-ID: On Mon, 9 Aug 2021 at 17:21, Raimo Niskanen wrote: > So, what says the Community? How important feature is it > to be able to connect nodes with different cookies? Consider another use-case that might inform a wider view: if I've got a cluster running with a fixed cookie, and I want to rotate that cookie (maybe in place, maybe as I bring new nodes into the cluster and retire old ones), how do I do that? Could the way that Erlang uses cookies be simplified (yet generalised) to handle both use cases? Is there a larger story hiding under all this? From depierre.thomas@REDACTED Tue Aug 10 11:12:04 2021 From: depierre.thomas@REDACTED (Thomas Depierre) Date: Tue, 10 Aug 2021 11:12:04 +0200 Subject: dbg function names In-Reply-To: References: <5db2ae39-6200-fc43-0c06-40765e9a9df7@stratus3d.com> Message-ID: Would it make sense to also consider adding "long names" to the API, possibly deprecating the short one over time ? Thomas Depierre On Tue, 10 Aug 2021 at 08:58, Lukas Larsson wrote: > Hello! > > On Sun, Aug 8, 2021 at 8:42 AM Trevor Brown wrote: > >> Hi, I've used the dbg module a fair bit over the years, and I am curious >> about the names of the functions. Looking at the list of functions, I >> came up with what I think each function name means: >> >> The function names are all acronyms (except for the ones that clearly >> aren't like `get_tracer/0` and `stop/0`) and stand for the following: >> >> * `c` stands for *c*lear >> > > I believe that the solitary `c` stands for *c*all. > > >> * `cn` stands for *c*lear *n*ode >> * `ctp` stands for *c*lear *t*race *p*attern >> * `ctpe` stands for *c*lear *t*race *p*attern *e*vent >> * `ctpg` stands for *c*lear *t*race *p*attern *g*lobal >> * `ctpl` stands for *c*lear *t*race *p*attern *l*ocal >> * `dtp` stands for *d*elete *t*race *p*attern (not sure if it's delete, >> drop, discard, etc...) >> > > If you type "dbg:h(dtp)" it prints: > > dtp() -> ok > - Deletes all saved match_spec's. > dtp(N) -> ok > - Deletes a specific saved match_spec. > > So it is `delete`, just as you guessed. > > >> * `wtp` stands for *w*rite *t*race *p*attern >> * `rtp` stands for *r*ead *t*race *p*attern >> * `n` stands for *n*ode >> * `i` stands for *i*nformation >> * `p` stands for *p*rocess >> * `tp` stands for *t*race *p*attern (implicitly global) >> * `tpl` stands for *t*race *p*attern *l*ocal >> * `h` stands for *h*elp >> * `ln` stands for *l*ist *n*odes >> * `ltp` stands for *l*ist *t*race *p*atterns >> >> Can anyone confirm if I am correct here? And if so, reference any docs >> explaining this? I personally find that understanding the acronyms makes >> the functions easier to remember, so it's a shame the official docs >> don't explain this if I am correct. >> > > I use the same words to describe the acronyms as you have done. I believe > the person that designed the dbg API has left the Erlang world for the time > being, so if we are incorrect we may never know. > > If you want to create a PR that adds the names that you have proposed into > the documentation I think that it could be a good starting point in making > the words behind the acronyms official. > > >> Also, I've always assumed the module name stood for debug, but is that >> true? I haven't found any docs on that either. >> > > I believe that you are correct, but I do not know for sure. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From raimo+erlang-questions@REDACTED Tue Aug 10 11:36:02 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Tue, 10 Aug 2021 11:36:02 +0200 Subject: Connecting cluster with different cookies In-Reply-To: References: <20210809162100.GA50019@erix.ericsson.se> Message-ID: <20210810093602.GA23223@erix.ericsson.se> On Tue, Aug 10, 2021 at 10:04:21AM +0100, Roger Lipscombe wrote: > On Mon, 9 Aug 2021 at 17:21, Raimo Niskanen > wrote: > > So, what says the Community? How important feature is it > > to be able to connect nodes with different cookies? > > Consider another use-case that might inform a wider view: if I've got > a cluster running with a fixed cookie, and I want to rotate that > cookie (maybe in place, maybe as I bring new nodes into the cluster > and retire old ones), how do I do that? Interesting idea. But using the current cookie concept for this; wouldn't that be to put too much faith in the cookies...? It sounds a bit like handling TLS certificates and revocations for a cluster. I here there are very complicated procedures for that. > > Could the way that Erlang uses cookies be simplified (yet generalised) > to handle both use cases? Is there a larger story hiding under all > this? I wrote an alternative distribution protocol for a benchmark test suite, that uses the one cookie as the encryption and authentication key for a cluster. The purpose was to have some kind of barebone encryption to compare the TLS distribution protocol with. To use a homebrewn encryption system in production is a known way to future catastrophic failure, but, ... in such a system it would make sense to have the possibility to change the cluster cookie while in a live cluster. Cheers -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From raimo+erlang-questions@REDACTED Tue Aug 10 11:38:05 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Tue, 10 Aug 2021 11:38:05 +0200 Subject: dbg function names In-Reply-To: References: <5db2ae39-6200-fc43-0c06-40765e9a9df7@stratus3d.com> Message-ID: <20210810093805.GB23223@erix.ericsson.se> On Tue, Aug 10, 2021 at 11:12:04AM +0200, Thomas Depierre wrote: > Would it make sense to also consider adding "long names" to the API, > possibly deprecating the short one over time ? I find the short names handy, but it would certainly not hurt to spell out the acronyms in the documentation and dbg:h(). / Raimo Niskanen > > Thomas Depierre > > > On Tue, 10 Aug 2021 at 08:58, Lukas Larsson wrote: > > > Hello! > > > > On Sun, Aug 8, 2021 at 8:42 AM Trevor Brown wrote: > > > >> Hi, I've used the dbg module a fair bit over the years, and I am curious > >> about the names of the functions. Looking at the list of functions, I > >> came up with what I think each function name means: > >> > >> The function names are all acronyms (except for the ones that clearly > >> aren't like `get_tracer/0` and `stop/0`) and stand for the following: > >> > >> * `c` stands for *c*lear > >> > > > > I believe that the solitary `c` stands for *c*all. > > > > > >> * `cn` stands for *c*lear *n*ode > >> * `ctp` stands for *c*lear *t*race *p*attern > >> * `ctpe` stands for *c*lear *t*race *p*attern *e*vent > >> * `ctpg` stands for *c*lear *t*race *p*attern *g*lobal > >> * `ctpl` stands for *c*lear *t*race *p*attern *l*ocal > >> * `dtp` stands for *d*elete *t*race *p*attern (not sure if it's delete, > >> drop, discard, etc...) > >> > > > > If you type "dbg:h(dtp)" it prints: > > > > dtp() -> ok > > - Deletes all saved match_spec's. > > dtp(N) -> ok > > - Deletes a specific saved match_spec. > > > > So it is `delete`, just as you guessed. > > > > > >> * `wtp` stands for *w*rite *t*race *p*attern > >> * `rtp` stands for *r*ead *t*race *p*attern > >> * `n` stands for *n*ode > >> * `i` stands for *i*nformation > >> * `p` stands for *p*rocess > >> * `tp` stands for *t*race *p*attern (implicitly global) > >> * `tpl` stands for *t*race *p*attern *l*ocal > >> * `h` stands for *h*elp > >> * `ln` stands for *l*ist *n*odes > >> * `ltp` stands for *l*ist *t*race *p*atterns > >> > >> Can anyone confirm if I am correct here? And if so, reference any docs > >> explaining this? I personally find that understanding the acronyms makes > >> the functions easier to remember, so it's a shame the official docs > >> don't explain this if I am correct. > >> > > > > I use the same words to describe the acronyms as you have done. I believe > > the person that designed the dbg API has left the Erlang world for the time > > being, so if we are incorrect we may never know. > > > > If you want to create a PR that adds the names that you have proposed into > > the documentation I think that it could be a good starting point in making > > the words behind the acronyms official. > > > > > >> Also, I've always assumed the module name stood for debug, but is that > >> true? I haven't found any docs on that either. > >> > > > > I believe that you are correct, but I do not know for sure. > > -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From mikpelinux@REDACTED Tue Aug 10 11:48:37 2021 From: mikpelinux@REDACTED (Mikael Pettersson) Date: Tue, 10 Aug 2021 11:48:37 +0200 Subject: Connecting cluster with different cookies In-Reply-To: References: <20210809162100.GA50019@erix.ericsson.se> Message-ID: On Tue, Aug 10, 2021 at 11:04 AM Roger Lipscombe wrote: > > On Mon, 9 Aug 2021 at 17:21, Raimo Niskanen > wrote: > > So, what says the Community? How important feature is it > > to be able to connect nodes with different cookies? > > Consider another use-case that might inform a wider view: if I've got > a cluster running with a fixed cookie, and I want to rotate that > cookie (maybe in place, maybe as I bring new nodes into the cluster > and retire old ones), how do I do that? I believe we have that use-case. Our main Erlang cluster is never supposed to be down (some nodes may be, but never all of them at once). If we were to have to rotate the cookie we'd need the ability to migrate nodes and connections incrementally while keeping the nodes still on the old cookie functional and connected. For that, set_cookie(OtherNode, OtherCookie) is required. (I'm on vacation now so can't check if/when we did this, but I'm pretty sure we did not too long ago.) From jose.valim@REDACTED Tue Aug 10 13:14:49 2021 From: jose.valim@REDACTED (=?UTF-8?Q?Jos=C3=A9_Valim?=) Date: Tue, 10 Aug 2021 13:14:49 +0200 Subject: Connecting cluster with different cookies In-Reply-To: <20210810085200.GA21612@erix.ericsson.se> References: <20210809162100.GA50019@erix.ericsson.se> <20210810085200.GA21612@erix.ericsson.se> Message-ID: Hi Raimo, we are using this feature in Livebook . Livebook is a web application for writing interactive code notebooks. In Livebook you can connect to any other Erlang node, with its own name and cookie, to programmatically extract information from a node, either of production data or of the VM itself, and build graphs, visualizations tables, etc. You can find a quick example on this tweet by Micha? Slaski of using it for VM instrumentation. The way it works is that we have a web app cluster running Livebook (the server). Then for each code notebook we spawn a separate VM to run the notebook code. So the Livebook cluster is managing several code runners. At this point, all server instances and all runners are using the same cookie. Then, if you want to connect to a separate production cluster, to gather information from it, you would call erlang:set_cookie(ProdNode, ProdCookie) from your code notebook. We could just change the runner's main cookie before we connect to ProdNode but that would make it impossible for other and new instances of the Livebook server to connect to said runner. Supporting a list of cookies would work for us though (and perhaps it could have other benefits too, such as secret rotation in live systems. you would temporarily support the old and new cookies for a time period while migration happens). -------------- next part -------------- An HTML attachment was scrubbed... URL: From attila.r.nohl@REDACTED Tue Aug 10 13:31:41 2021 From: attila.r.nohl@REDACTED (Attila Rajmund Nohl) Date: Tue, 10 Aug 2021 13:31:41 +0200 Subject: Can't see symbols from Erlang NIF library in core file In-Reply-To: References: Message-ID: Hello! The solution was to start the VM with -debug, so I got a crash at one of the asserts and that led me to the bug. The 3rd party library is stripped, but I thought that my code should be somewhere in the call stack and gdb should show it.... My bug was that I released an other resource than I wanted, so there was a "double free", probably leading to memory corruption and it might explain that the call stack was so bad. Lukas Larsson ezt ?rta (id?pont: 2021. aug. 10., K, 9:07): > > Hello! > > Did you manage to figure out how to get symbols for your nif? There should not be anything special that you have to do other than compiling the nif with debug symbols. Could it be the 3rd party C library that does not have symbols? > > On Tue, Jul 20, 2021 at 7:38 PM Attila Rajmund Nohl wrote: >> >> Hello! >> >> I'm working on an Erlang wrapper over a 3rd party C library on Ubuntu >> Linux on x86, so I'm creating a NIF. Sometimes my code (I think) >> crashes, resulting in a core file. Unfortunately the stacktrace is not >> really helpful: >> >> (gdb) bt >> #0 0x00007fc22229968a in ?? () >> #1 0x0000000060e816d8 in ?? () >> #2 0x0000000007cd48b0 in ?? () >> #3 0x00007fc228031410 in ?? () >> #4 0x00007fc228040b80 in ?? () >> #5 0x00007fc228040c50 in ?? () >> #6 0x00007fc22223de0b in ?? () >> #7 0x0000000000000000 in ?? () >> >> even though I built my NIF .so file with debug info: >> >> ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically >> linked, BuildID[sha1]=b70dd1f2450f5c0e9980c8396aaad2e1cd29024c, with >> debug_info, not stripped >> >> The beam binary also has debug info: >> >> ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically >> linked, interpreter /lib64/ld-linux-x86-64.so.2, >> BuildID[sha1]=e0a5dba6507b8c2b333faebc89fbc6ea2f7263b9, for GNU/Linux >> 3.2.0, with debug_info, not stripped >> >> However, info sharedlibrary doesn't show neither the NIF nor the 3rd party lib: >> >> (gdb) info sharedlibrary >> From To Syms Read Shared Object Library >> 0x00007fc28942ed50 0x00007fc289432004 Yes >> /lib/x86_64-linux-gnu/libgtk3-nocsd.so.0 >> 0x00007fc289429220 0x00007fc28942a179 Yes >> /lib/x86_64-linux-gnu/libdl.so.2 >> 0x00007fc2892e83c0 0x00007fc28938ef18 Yes >> /lib/x86_64-linux-gnu/libm.so.6 >> 0x00007fc2892b76a0 0x00007fc2892c517c Yes >> /lib/x86_64-linux-gnu/libtinfo.so.6 >> 0x00007fc28928dae0 0x00007fc28929d4d5 Yes >> /lib/x86_64-linux-gnu/libpthread.so.0 >> 0x00007fc2890b9630 0x00007fc28922e20d Yes >> /lib/x86_64-linux-gnu/libc.so.6 >> 0x00007fc289657100 0x00007fc289679674 Yes (*) /lib64/ld-linux-x86-64.so.2 >> 0x00007fc24459c040 0x00007fc2445ab8ad Yes >> /home/nar/otp/23.3.4.2/lib/crypto-4.9.0.2/priv/lib/crypto.so >> 0x00007fc2239e3000 0x00007fc223b7c800 Yes (*) >> /lib/x86_64-linux-gnu/libcrypto.so.1.1 >> 0x00007fc2896500e0 0x00007fc28965028c Yes >> /home/nar/otp/23.3.4.2/lib/crypto-4.9.0.2/priv/lib/crypto_callback.so >> 0x00007fc289649380 0x00007fc28964bc1c Yes >> /home/nar/otp/23.3.4.2/lib/asn1-5.0.15/priv/lib/asn1rt_nif.so >> 0x00007fc289638720 0x00007fc28963bd70 Yes >> /lib/x86_64-linux-gnu/librt.so.1 > > > The asn1rt_nif.so and crypto.so nifs have no special treatment and are loaded in exactly the same way as a user-defined nif. So there is most likely something different/wrong with how your nif is compiled and/or loaded. > >> >> >> I found an answer at stackoverflow >> (https://stackoverflow.com/a/32727752/2414208) mentioning that "The >> Erlang VM doesn't load NIF libraries with global symbols exposed". >> Could this be the reason why I don't see the symbols? Is there a way >> to tell gdb to look up symbols from my .so file? > > > I don't think the stackoverflow question is related to your problem as it seems to be related to symbols not resolving when doing dlopen and not when using gdb. > > From lukas@REDACTED Tue Aug 10 14:09:17 2021 From: lukas@REDACTED (Lukas Larsson) Date: Tue, 10 Aug 2021 14:09:17 +0200 Subject: Can't see symbols from Erlang NIF library in core file In-Reply-To: References: Message-ID: On Tue, Aug 10, 2021 at 1:31 PM Attila Rajmund Nohl wrote: > Hello! > > The solution was to start the VM with -debug, so I got a crash at one > of the asserts and that led me to the bug. The 3rd party library is > stripped, but I thought that my code should be somewhere in the call > stack and gdb should show it.... My bug was that I released an other > resource than I wanted, so there was a "double free", probably leading > to memory corruption and it might explain that the call stack was so > bad. > Great that you found the bug! Running the debug emulator is always a good idea to catch errors in NIFs. Depending on what flags were used to compile the third-party library, gdb may need the debug information to properly rewind the stack so that you can see your own frame. > Lukas Larsson ezt ?rta (id?pont: 2021. aug. 10., K, > 9:07): > > > > Hello! > > > > Did you manage to figure out how to get symbols for your nif? There > should not be anything special that you have to do other than compiling the > nif with debug symbols. Could it be the 3rd party C library that does not > have symbols? > > > > On Tue, Jul 20, 2021 at 7:38 PM Attila Rajmund Nohl < > attila.r.nohl@REDACTED> wrote: > >> > >> Hello! > >> > >> I'm working on an Erlang wrapper over a 3rd party C library on Ubuntu > >> Linux on x86, so I'm creating a NIF. Sometimes my code (I think) > >> crashes, resulting in a core file. Unfortunately the stacktrace is not > >> really helpful: > >> > >> (gdb) bt > >> #0 0x00007fc22229968a in ?? () > >> #1 0x0000000060e816d8 in ?? () > >> #2 0x0000000007cd48b0 in ?? () > >> #3 0x00007fc228031410 in ?? () > >> #4 0x00007fc228040b80 in ?? () > >> #5 0x00007fc228040c50 in ?? () > >> #6 0x00007fc22223de0b in ?? () > >> #7 0x0000000000000000 in ?? () > >> > >> even though I built my NIF .so file with debug info: > >> > >> ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically > >> linked, BuildID[sha1]=b70dd1f2450f5c0e9980c8396aaad2e1cd29024c, with > >> debug_info, not stripped > >> > >> The beam binary also has debug info: > >> > >> ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically > >> linked, interpreter /lib64/ld-linux-x86-64.so.2, > >> BuildID[sha1]=e0a5dba6507b8c2b333faebc89fbc6ea2f7263b9, for GNU/Linux > >> 3.2.0, with debug_info, not stripped > >> > >> However, info sharedlibrary doesn't show neither the NIF nor the 3rd > party lib: > >> > >> (gdb) info sharedlibrary > >> From To Syms Read Shared Object > Library > >> 0x00007fc28942ed50 0x00007fc289432004 Yes > >> /lib/x86_64-linux-gnu/libgtk3-nocsd.so.0 > >> 0x00007fc289429220 0x00007fc28942a179 Yes > >> /lib/x86_64-linux-gnu/libdl.so.2 > >> 0x00007fc2892e83c0 0x00007fc28938ef18 Yes > >> /lib/x86_64-linux-gnu/libm.so.6 > >> 0x00007fc2892b76a0 0x00007fc2892c517c Yes > >> /lib/x86_64-linux-gnu/libtinfo.so.6 > >> 0x00007fc28928dae0 0x00007fc28929d4d5 Yes > >> /lib/x86_64-linux-gnu/libpthread.so.0 > >> 0x00007fc2890b9630 0x00007fc28922e20d Yes > >> /lib/x86_64-linux-gnu/libc.so.6 > >> 0x00007fc289657100 0x00007fc289679674 Yes (*) > /lib64/ld-linux-x86-64.so.2 > >> 0x00007fc24459c040 0x00007fc2445ab8ad Yes > >> /home/nar/otp/23.3.4.2/lib/crypto-4.9.0.2/priv/lib/crypto.so > >> 0x00007fc2239e3000 0x00007fc223b7c800 Yes (*) > >> /lib/x86_64-linux-gnu/libcrypto.so.1.1 > >> 0x00007fc2896500e0 0x00007fc28965028c Yes > >> /home/nar/otp/23.3.4.2/lib/crypto-4.9.0.2/priv/lib/crypto_callback.so > >> 0x00007fc289649380 0x00007fc28964bc1c Yes > >> /home/nar/otp/23.3.4.2/lib/asn1-5.0.15/priv/lib/asn1rt_nif.so > >> 0x00007fc289638720 0x00007fc28963bd70 Yes > >> /lib/x86_64-linux-gnu/librt.so.1 > > > > > > The asn1rt_nif.so and crypto.so nifs have no special treatment and are > loaded in exactly the same way as a user-defined nif. So there is most > likely something different/wrong with how your nif is compiled and/or > loaded. > > > >> > >> > >> I found an answer at stackoverflow > >> (https://stackoverflow.com/a/32727752/2414208) mentioning that "The > >> Erlang VM doesn't load NIF libraries with global symbols exposed". > >> Could this be the reason why I don't see the symbols? Is there a way > >> to tell gdb to look up symbols from my .so file? > > > > > > I don't think the stackoverflow question is related to your problem as > it seems to be related to symbols not resolving when doing dlopen and not > when using gdb. > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From t@REDACTED Tue Aug 10 16:08:48 2021 From: t@REDACTED (Tristan Sloughter) Date: Tue, 10 Aug 2021 08:08:48 -0600 Subject: Connecting cluster with different cookies In-Reply-To: <20210810085746.GF21612@erix.ericsson.se> References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> <45c2095e-5d68-4552-9e3b-afc416f3c332@www.fastmail.com> <20210810085746.GF21612@erix.ericsson.se> Message-ID: It would not be for the latter case of a tool for administering multiple clusters. On Tue, Aug 10, 2021, at 02:57, Raimo Niskanen wrote: > Would it be sufficient to be able to set the default cookie > for a node with e.g a new API function erlang:set_cookie(Cookie)? > > / Raimo Niskanen > > > On Mon, Aug 09, 2021 at 01:56:34PM -0600, Tristan Sloughter wrote: > > It is used in `nodetool` and `install_upgrade_escript` in relx. > > > > I know I've used it elsewhere too but can't think of where... may have just been toying with creating tools for managing multiple clusters. > > -- > > / Raimo Niskanen, Erlang/OTP, Ericsson AB > From james@REDACTED Tue Aug 10 17:41:12 2021 From: james@REDACTED (James Aimonetti) Date: Tue, 10 Aug 2021 08:41:12 -0700 Subject: Connecting cluster with different cookies In-Reply-To: <20210810085636.GC21612@erix.ericsson.se> References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> <20210810085636.GC21612@erix.ericsson.se> Message-ID: <871r71z4rr.fsf@compy64.2600hz.com> Raimo Niskanen writes: > Would it be sufficient to be able to set the default cookie > for a node with e.g a new API function erlang:set_cookie(Cookie)? The setup would be two+ Erlang nodes connect to N FreeSWITCH C-nodes. Each FreeSWITCH C-node can set an independent cookie value; this value is stored in a config database that the Erlang nodes use when connecting to the C-nodes. The Erlang nodes have their own unique cookie as well, set at startup. But this feature is not used, according to my brief survey of our community that might even know about it (most did not). Most everyone matches the Erlang nodes' cookie to their C-node configuration's cookie, so no extra database configuration is required. So more just a datapoint that set_cookie/2 was known and thought to be useful 8ish years ago :) But is not relevant for our usecase anymore. -- James Aimonetti Lead Systems Architect 2600Hz | http://2600hz.com | UCaaS CPaaS CCaaS tel:415.886.7905 irc:mc_ @ libera.chat #2600hz From msheldon@REDACTED Wed Aug 11 00:37:32 2021 From: msheldon@REDACTED (Mark Sheldon) Date: Tue, 10 Aug 2021 18:37:32 -0400 Subject: Connecting cluster with different cookies In-Reply-To: <20210810085659.GD21612@erix.ericsson.se> References: <20210809162100.GA50019@erix.ericsson.se> <877dguzi4f.fsf@compy64.2600hz.com> <20210810085659.GD21612@erix.ericsson.se> Message-ID: Yes, I think so. Of course, the client and server suctions are in the same source file. The client functions all eventually do erlang:set_cookie(node(), ?COOKIE), which is exactly what you are proposing. The server boot process does erlang:set_cookie(?SERVER_NODE, ?COOKIE), but that is only run when booting the server, i. e., that code is running on the server node and node() would be the same thing. So, again, a long-winded yes, for my current stuff, it should be sufficient to set the current node?s cookie -) -Mark Mark A. Sheldon msheldon@REDACTED > On 10Aug, 2021, at 04:57, Raimo Niskanen wrote: > > Would it be sufficient to be able to set the default cookie > for a node with e.g a new API function erlang:set_cookie(Cookie)? > > / Raimo Niskanen > > > On Mon, Aug 09, 2021 at 01:29:15PM -0400, Mark Sheldon wrote: >> I don?t represent a large application, but perhaps this is a common use case ? or perhaps someone can give me a better way to do this. >> >> I use erlang:set_cookie/2 in escripts I have my students (and potentially teaching assistants) use to communicate with Erlang services I provide. For example, I have a script for submitting late work that captures dates on students files and sends the student?s submission and metadata to an Erlang server. >> >> These programs are run by students whose accounts I cannot control. They are not in any privileged Unix group, and they will not have a cookie file in their home directories. So, the scripts explicitly set the cookie so that they can communicate with my server(s). >> >> An analogous situation could arise if I want to have a web page interact with a service. The department uses Apache and supports CGI scripts. I can write an escripts in the same way as above. >> >> I don?t run that many services, but it seems reasonable to have services available to staff that are different from students and to use different cookies for the two groups of nodes. >> >> I understand that it?s not great security. But the scripts can only be run people with department accounts, and the network is behind a firewall. >> >> If I have missed a better solution, I?d be interested to hear about it. I mostly hacked the late submission system together one afternoon as a more fun approach to a common problem, and I?ve been using it ever since. >> >> -Mark >> >> >> Mark A. Sheldon >> Associate Teaching Professor >> Department of Computer Science >> Tufts University >> >> >>> On 9Aug, 2021, at 12:40, James Aimonetti wrote: >>> >>> >>> Raimo Niskanen writes: >>> >>>> The question is now, is this an essential feature / how >>>> important is this feature? >>>> >>> >>> In the KAZOO project, we support setting different cookies for >>> connecting to our C-node code in the FreeSWITCH project. This has been >>> in place for over 8 years. >>> >>> While I do not think anyone really uses this feature, I also know that >>> with our recent preliminary release of KAZOO 5.0, we've found folks >>> using corners of the software that we did not anticipate. >>> >>> I would not call this an essential feature for our project, personally, >>> but I am also not relishing finding that one cluster which relies on >>> unique cookies for some reason. >>> >>> I've put out a question to our OPS team and our open source forum. If >>> any users require it as part of their operations, I'll forward that >>> along. >>> >>> -- >>> James Aimonetti >>> >>> Lead Systems Architect >>> 2600Hz | http://2600hz.com | UCaaS CPaaS CCaaS >>> tel:415.886.7905 >>> irc:mc_ @ libera.chat #2600hz >> > > -- > > / Raimo Niskanen, Erlang/OTP, Ericsson AB -------------- next part -------------- An HTML attachment was scrubbed... URL: From prof3ta@REDACTED Wed Aug 11 09:10:10 2021 From: prof3ta@REDACTED (Roberto Aloi) Date: Wed, 11 Aug 2021 09:10:10 +0200 Subject: Connecting cluster with different cookies In-Reply-To: <20210809162100.GA50019@erix.ericsson.se> References: <20210809162100.GA50019@erix.ericsson.se> Message-ID: Hi Raimo, We use `erlang:set_cookie/2` with a remote node in Erlang LS, too. Things can probably be refactored to avoid that, but the existing API proved to be handy over the years. Looking at GitHub, other projects use that API, too (e.g. redbug). I have always been thinking (maybe erroneously) of the cookie as a property of the "connection" between two nodes (with a default one), not a property of the single node. With that mindset, the `erlang:set_cookie/2` API made sense. This was useful when building "topologies" of nodes (e.g. nodes A, B and C where B can connect to A and C but A cannot connect to C), especially during tests. Reflecting on this, what seems inconsistent in the API is the lack of a `get_cookie/1` which would return the current cookie for the "connection" from the current node's perspective (or alternatively a `erlang:get_cookies/0` which returns all of them). Roberto On Mon, 9 Aug 2021 at 18:21, Raimo Niskanen < raimo+erlang-questions@REDACTED> wrote: > Hello Community. > > Regarding a GitHub Issue in progress: > https://github.com/erlang/otp/issues/5063, > and a corresponding pull request: > https://github.com/erlang/otp/pull/5062 > > There is an apparently rarely known API call > erlang:set_cookie(Node, Cookie) that allows you to configure > a cookie to use when communicating with a different node. > > This/these set cookie/s may/should be different from the node's > normal (default) cookie, and the functionality exists > to make it possible to connect nodes that have different > default cookies. > > The feature is probably rarely used; almost nobody in the > OTP group knew that it existed nor how it is supposed > to be used. Connecting only nodes with the same cookie > seems to be the norm. > > The question is now, is this an essential feature / how > important is this feature? > > To completely remove this feature would simplify the code, > but if that should destroy an important use case; removing > would not be an option. > > The Issue and PR is about how it is supposed to work; if and > how it should be fixed. > > > So, what says the Community? How important feature is it > to be able to connect nodes with different cookies? > > Cheers > -- > > / Raimo Niskanen, Erlang/OTP, Ericsson AB > -------------- next part -------------- An HTML attachment was scrubbed... URL: From admin@REDACTED Wed Aug 11 02:57:32 2021 From: admin@REDACTED (Trevor Brown) Date: Tue, 10 Aug 2021 20:57:32 -0400 Subject: dbg function names In-Reply-To: <20210810093805.GB23223@erix.ericsson.se> References: <5db2ae39-6200-fc43-0c06-40765e9a9df7@stratus3d.com> <20210810093805.GB23223@erix.ericsson.se> Message-ID: <94f61893-acb1-c59e-2c23-99b84af5d354@stratus3d.com> I agree. The short names are nice because they are fast to type. And if you memorize the phrase for each acronym it makes it easy to determine what function you need to invoke. I am going to create a PR to list the acronyms in the docs and dbg:h/0. Trevor On 8/10/21 5:38 AM, Raimo Niskanen wrote: > On Tue, Aug 10, 2021 at 11:12:04AM +0200, Thomas Depierre wrote: >> Would it make sense to also consider adding "long names" to the API, >> possibly deprecating the short one over time ? > I find the short names handy, but it would certainly not hurt to > spell out the acronyms in the documentation and dbg:h(). > > / Raimo Niskanen > > > >> Thomas Depierre >> >> >> On Tue, 10 Aug 2021 at 08:58, Lukas Larsson wrote: >> >>> Hello! >>> >>> On Sun, Aug 8, 2021 at 8:42 AM Trevor Brown wrote: >>> >>>> Hi, I've used the dbg module a fair bit over the years, and I am curious >>>> about the names of the functions. Looking at the list of functions, I >>>> came up with what I think each function name means: >>>> >>>> The function names are all acronyms (except for the ones that clearly >>>> aren't like `get_tracer/0` and `stop/0`) and stand for the following: >>>> >>>> * `c` stands for *c*lear >>>> >>> I believe that the solitary `c` stands for *c*all. >>> >>> >>>> * `cn` stands for *c*lear *n*ode >>>> * `ctp` stands for *c*lear *t*race *p*attern >>>> * `ctpe` stands for *c*lear *t*race *p*attern *e*vent >>>> * `ctpg` stands for *c*lear *t*race *p*attern *g*lobal >>>> * `ctpl` stands for *c*lear *t*race *p*attern *l*ocal >>>> * `dtp` stands for *d*elete *t*race *p*attern (not sure if it's delete, >>>> drop, discard, etc...) >>>> >>> If you type "dbg:h(dtp)" it prints: >>> >>> dtp() -> ok >>> - Deletes all saved match_spec's. >>> dtp(N) -> ok >>> - Deletes a specific saved match_spec. >>> >>> So it is `delete`, just as you guessed. >>> >>> >>>> * `wtp` stands for *w*rite *t*race *p*attern >>>> * `rtp` stands for *r*ead *t*race *p*attern >>>> * `n` stands for *n*ode >>>> * `i` stands for *i*nformation >>>> * `p` stands for *p*rocess >>>> * `tp` stands for *t*race *p*attern (implicitly global) >>>> * `tpl` stands for *t*race *p*attern *l*ocal >>>> * `h` stands for *h*elp >>>> * `ln` stands for *l*ist *n*odes >>>> * `ltp` stands for *l*ist *t*race *p*atterns >>>> >>>> Can anyone confirm if I am correct here? And if so, reference any docs >>>> explaining this? I personally find that understanding the acronyms makes >>>> the functions easier to remember, so it's a shame the official docs >>>> don't explain this if I am correct. >>>> >>> I use the same words to describe the acronyms as you have done. I believe >>> the person that designed the dbg API has left the Erlang world for the time >>> being, so if we are incorrect we may never know. >>> >>> If you want to create a PR that adds the names that you have proposed into >>> the documentation I think that it could be a good starting point in making >>> the words behind the acronyms official. >>> >>> >>>> Also, I've always assumed the module name stood for debug, but is that >>>> true? I haven't found any docs on that either. >>>> >>> I believe that you are correct, but I do not know for sure. >>> From admin@REDACTED Wed Aug 11 03:32:39 2021 From: admin@REDACTED (Trevor Brown) Date: Tue, 10 Aug 2021 21:32:39 -0400 Subject: dbg function names In-Reply-To: References: <5db2ae39-6200-fc43-0c06-40765e9a9df7@stratus3d.com> Message-ID: <0c736bc3-376f-1e27-7a76-fd50d95eb73d@stratus3d.com> I am working on a pull request now to add this information to the docs and possibly dbg:h/0. Even if we aren't completely correct on the meaning of the acronyms, I think explaining them in the docs will help make the API less esoteric. I came across someone who didn't know what the tpl function name stood for and assumed it meant tuple. That's one of the things that prompted me to look into this. Trevor On 8/10/21 2:58 AM, Lukas Larsson wrote: > Hello! > > On Sun, Aug 8, 2021 at 8:42 AM Trevor Brown > wrote: > > Hi, I've used the dbg module a fair bit over the years, and I am > curious > about the names of the functions. Looking at the list of functions, I > came up with what I think each function name means: > > The function names are all acronyms (except for the ones that clearly > aren't like `get_tracer/0` and `stop/0`) and stand for the following: > > * `c` stands for *c*lear > > > I believe that the solitary `c` stands for *c*all. > ? > > * `cn` stands for *c*lear *n*ode > * `ctp` stands for *c*lear *t*race *p*attern > * `ctpe` stands for *c*lear *t*race *p*attern *e*vent > * `ctpg` stands for *c*lear *t*race *p*attern *g*lobal > * `ctpl` stands for *c*lear *t*race *p*attern *l*ocal > * `dtp` stands for *d*elete *t*race *p*attern (not sure if it's > delete, > drop, discard, etc...) > > > If you type "dbg:h(dtp)" it prints:? > > dtp() -> ok > ?- Deletes all saved match_spec's. > dtp(N) -> ok > ?- Deletes a specific saved match_spec. > > So it is `delete`, just as you guessed. > ? > > * `wtp` stands for *w*rite *t*race *p*attern > * `rtp` stands for *r*ead *t*race *p*attern > * `n` stands for *n*ode > * `i` stands for *i*nformation > * `p` stands for *p*rocess > * `tp` stands for *t*race *p*attern (implicitly global) > * `tpl` stands for *t*race *p*attern *l*ocal > * `h` stands for *h*elp > * `ln` stands for *l*ist *n*odes > * `ltp` stands for *l*ist *t*race *p*atterns > > Can anyone confirm if I am correct here? And if so, reference any docs > explaining this? I personally find that understanding the acronyms > makes > the functions easier to remember, so it's a shame the official docs > don't explain this if I am correct. > > > I use the same words to describe the acronyms as you have done. I > believe the person that designed the dbg API has left the Erlang world > for the time being, so if we are incorrect we may never know. > > If you want to create a PR that adds the names that you have proposed > into the documentation I think that it could be a good starting point > in making the words behind the acronyms official. > > > Also, I've always assumed the module name stood for debug, but is that > true? I haven't found any docs on that either. > > > I believe that you are correct, but I do not know for sure. -------------- next part -------------- An HTML attachment was scrubbed... URL: From admin@REDACTED Wed Aug 11 14:19:53 2021 From: admin@REDACTED (Trevor Brown) Date: Wed, 11 Aug 2021 08:19:53 -0400 Subject: dbg function names In-Reply-To: <0c736bc3-376f-1e27-7a76-fd50d95eb73d@stratus3d.com> References: <5db2ae39-6200-fc43-0c06-40765e9a9df7@stratus3d.com> <0c736bc3-376f-1e27-7a76-fd50d95eb73d@stratus3d.com> Message-ID: <529618e4-b5f6-d7e4-983f-21f567626ed8@stratus3d.com> Hi Lukas, Can you suggest how to format the acronym meaning for each function name? For example, for the `h/0` function: I can put it at the end of the description: > Gives a brief help text for functions in the dbg module. The available items can be listed with dbg:h/0. `h` stands for *h*elp. Or at the beginning: > `h` stands for *h*elp. Gives a brief help text for functions in the dbg module. The available items can be listed with dbg:h/0. The description for the help function is short, but some of the other functions have long descriptions with lots of details. Putting the acronym explanation at the bottom might result in most people missing it. Thoughts? Trevor On 8/10/21 9:32 PM, Trevor Brown wrote: > > I am working on a pull request now to add this information to the docs > and possibly dbg:h/0. > > Even if we aren't completely correct on the meaning of the acronyms, I > think explaining them in the docs will help make the API less > esoteric. I came across someone who didn't know what the tpl function > name stood for and assumed it meant tuple. That's one of the things > that prompted me to look into this. > > Trevor > > On 8/10/21 2:58 AM, Lukas Larsson wrote: >> Hello! >> >> On Sun, Aug 8, 2021 at 8:42 AM Trevor Brown > > wrote: >> >> Hi, I've used the dbg module a fair bit over the years, and I am >> curious >> about the names of the functions. Looking at the list of functions, I >> came up with what I think each function name means: >> >> The function names are all acronyms (except for the ones that clearly >> aren't like `get_tracer/0` and `stop/0`) and stand for the following: >> >> * `c` stands for *c*lear >> >> >> I believe that the solitary `c` stands for *c*all. >> ? >> >> * `cn` stands for *c*lear *n*ode >> * `ctp` stands for *c*lear *t*race *p*attern >> * `ctpe` stands for *c*lear *t*race *p*attern *e*vent >> * `ctpg` stands for *c*lear *t*race *p*attern *g*lobal >> * `ctpl` stands for *c*lear *t*race *p*attern *l*ocal >> * `dtp` stands for *d*elete *t*race *p*attern (not sure if it's >> delete, >> drop, discard, etc...) >> >> >> If you type "dbg:h(dtp)" it prints:? >> >> dtp() -> ok >> ?- Deletes all saved match_spec's. >> dtp(N) -> ok >> ?- Deletes a specific saved match_spec. >> >> So it is `delete`, just as you guessed. >> ? >> >> * `wtp` stands for *w*rite *t*race *p*attern >> * `rtp` stands for *r*ead *t*race *p*attern >> * `n` stands for *n*ode >> * `i` stands for *i*nformation >> * `p` stands for *p*rocess >> * `tp` stands for *t*race *p*attern (implicitly global) >> * `tpl` stands for *t*race *p*attern *l*ocal >> * `h` stands for *h*elp >> * `ln` stands for *l*ist *n*odes >> * `ltp` stands for *l*ist *t*race *p*atterns >> >> Can anyone confirm if I am correct here? And if so, reference any >> docs >> explaining this? I personally find that understanding the >> acronyms makes >> the functions easier to remember, so it's a shame the official docs >> don't explain this if I am correct. >> >> >> I use the same words to describe the acronyms as you have done. I >> believe the person that designed the dbg API has left the Erlang >> world for the time being, so if we are incorrect we may never know. >> >> If you want to create a PR that adds the names that you have proposed >> into the documentation I think that it could be a good starting point >> in making the words behind the acronyms official. >> >> >> Also, I've always assumed the module name stood for debug, but is >> that >> true? I haven't found any docs on that either. >> >> >> I believe that you are correct, but I do not know for sure. -------------- next part -------------- An HTML attachment was scrubbed... URL: From raimo+erlang-questions@REDACTED Thu Aug 12 14:47:23 2021 From: raimo+erlang-questions@REDACTED (Raimo Niskanen) Date: Thu, 12 Aug 2021 14:47:23 +0200 Subject: Connecting cluster with different cookies In-Reply-To: <20210809162100.GA50019@erix.ericsson.se> References: <20210809162100.GA50019@erix.ericsson.se> Message-ID: <20210812124723.GA34664@erix.ericsson.se> I conclude that all these answers seems like the tip of an iceberg, and that we should keep this functionaliy. In [PR 5111](https://github.com/erlang/otp/pull/5111), a response to [Issue #5063](https://github.com/erlang/otp/issues/5063), I clarify the documentation, extend the functionality, and clean up the code. Comments are welcome. Cheers / Raimo Niskanen On Mon, Aug 09, 2021 at 06:21:00PM +0200, Raimo Niskanen wrote: > Hello Community. > > Regarding a GitHub Issue in progress: > https://github.com/erlang/otp/issues/5063, > and a corresponding pull request: > https://github.com/erlang/otp/pull/5062 > > There is an apparently rarely known API call > erlang:set_cookie(Node, Cookie) that allows you to configure > a cookie to use when communicating with a different node. > > This/these set cookie/s may/should be different from the node's > normal (default) cookie, and the functionality exists > to make it possible to connect nodes that have different > default cookies. > > The feature is probably rarely used; almost nobody in the > OTP group knew that it existed nor how it is supposed > to be used. Connecting only nodes with the same cookie > seems to be the norm. > > The question is now, is this an essential feature / how > important is this feature? > > To completely remove this feature would simplify the code, > but if that should destroy an important use case; removing > would not be an option. > > The Issue and PR is about how it is supposed to work; if and > how it should be fixed. > > > So, what says the Community? How important feature is it > to be able to connect nodes with different cookies? > > Cheers > -- > > / Raimo Niskanen, Erlang/OTP, Ericsson AB -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From serge@REDACTED Fri Aug 13 01:32:10 2021 From: serge@REDACTED (Serge Aleynikov) Date: Thu, 12 Aug 2021 19:32:10 -0400 Subject: [ANN] etrans Message-ID: I'd like to announce the release of etrans - the set of parse transforms that bring some convenient syntax features that improve code readability: https://github.com/saleyn/etran etrans implements an Elixir-like pipeline using the following syntax: print(A) -> [A] / element(1, A) / io:format("~s\n", [_]). test(Arg1, Arg2) -> [Arg1, Arg2] / fun1 / mod:fun2 / fun3() / fun4(Arg3, _) / io_lib:format("~p\n", [_]) / fun6([1,2,3], _, other_param) / fun7. Additionally, it implements ternary "if" (i.e. iif(Cond, True, False)), and stringification transforms, including "throw(Format, Args)". Enjoy! Serge -------------- next part -------------- An HTML attachment was scrubbed... URL: From ulf@REDACTED Fri Aug 13 10:19:12 2021 From: ulf@REDACTED (Ulf Wiger) Date: Fri, 13 Aug 2021 10:19:12 +0200 Subject: [ANN] etrans In-Reply-To: References: Message-ID: Is it just me, or is there something wrong with the pipeline example in the README? https://github.com/saleyn/etran#erlang-pipeline-erlpipe `Arg3` seems to be unbound. There is also a '.' ending the `fun6` line. Also, eunit seems to fail on an 'iif' transform. Other than that ... ;-) BR, Ulf On Fri, Aug 13, 2021 at 1:32 AM Serge Aleynikov wrote: > I'd like to announce the release of etrans - the set of parse transforms > that bring some convenient syntax features that improve code readability: > > https://github.com/saleyn/etran > > etrans implements an Elixir-like pipeline using the following syntax: > > print(A) -> > [A] / element(1, A) > / io:format("~s\n", [_]). > > test(Arg1, Arg2) -> > [Arg1, Arg2] > / fun1 > / mod:fun2 > / fun3() > / fun4(Arg3, _) > / io_lib:format("~p\n", [_]) > / fun6([1,2,3], _, other_param) > / fun7. > > Additionally, it implements ternary "if" (i.e. iif(Cond, True, False)), > and stringification transforms, including "throw(Format, Args)". > > Enjoy! > > Serge > -------------- next part -------------- An HTML attachment was scrubbed... URL: From serge@REDACTED Fri Aug 13 15:49:34 2021 From: serge@REDACTED (Serge Aleynikov) Date: Fri, 13 Aug 2021 09:49:34 -0400 Subject: [ANN] etrans In-Reply-To: References: Message-ID: Thank you! I fixed the typos in the README. The iif unit tests seem to run without errors in the github workflow. Could you create an issue if you see one? https://github.com/saleyn/etran On Fri, Aug 13, 2021 at 4:19 AM Ulf Wiger wrote: > Is it just me, or is there something wrong with the pipeline example in > the README? > > https://github.com/saleyn/etran#erlang-pipeline-erlpipe > > `Arg3` seems to be unbound. There is also a '.' ending the `fun6` line. > > Also, eunit seems to fail on an 'iif' transform. > > Other than that ... ;-) > > BR, > Ulf > > On Fri, Aug 13, 2021 at 1:32 AM Serge Aleynikov > wrote: > >> I'd like to announce the release of etrans - the set of parse transforms >> that bring some convenient syntax features that improve code readability: >> >> https://github.com/saleyn/etran >> >> etrans implements an Elixir-like pipeline using the following syntax: >> >> print(A) -> >> [A] / element(1, A) >> / io:format("~s\n", [_]). >> >> test(Arg1, Arg2) -> >> [Arg1, Arg2] >> / fun1 >> / mod:fun2 >> / fun3() >> / fun4(Arg3, _) >> / io_lib:format("~p\n", [_]) >> / fun6([1,2,3], _, other_param) >> / fun7. >> >> Additionally, it implements ternary "if" (i.e. iif(Cond, True, False)), >> and stringification transforms, including "throw(Format, Args)". >> >> Enjoy! >> >> Serge >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lloyd@REDACTED Fri Aug 13 21:44:29 2021 From: lloyd@REDACTED (Lloyd R. Prentice) Date: Fri, 13 Aug 2021 15:44:29 -0400 Subject: Long string to short ID Message-ID: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> Hello, What might be a nifty way to turn a long book title with spaces into a short human-readable ID? Thanks, LRP Sent from my iPad From dieter@REDACTED Fri Aug 13 22:11:06 2021 From: dieter@REDACTED (=?ISO-8859-1?Q?Dieter_Sch=F6n?=) Date: Fri, 13 Aug 2021 22:11:06 +0200 Subject: Long string to short ID In-Reply-To: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> References: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> Message-ID: Maybe use the ISBN, if the use case is for regular printed books? Regards, Dieter Am 13. August 2021 21:44:29 MESZ schrieb "Lloyd R. Prentice" : >Hello, > >What might be a nifty way to turn a long book title with spaces into a short human-readable ID? > >Thanks, > >LRP > >Sent from my iPad -- Diese Nachricht wurde von meinem Android-Ger?t mit K-9 Mail gesendet. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hugo@REDACTED Fri Aug 13 22:19:30 2021 From: hugo@REDACTED (Hugo Mills) Date: Fri, 13 Aug 2021 21:19:30 +0100 Subject: Long string to short ID In-Reply-To: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> References: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> Message-ID: <20210813201930.GB15870@savella.carfax.org.uk> On Fri, Aug 13, 2021 at 03:44:29PM -0400, Lloyd R. Prentice wrote: > Hello, > > What might be a nifty way to turn a long book title with spaces into a short human-readable ID? Depends rather on what purpose you want to put this ID to. One solution would be to hash it (with, say sha256). If the hash is too long for "short", truncate it. Note that this is not a globally-unique value, as there are lots of books with identical titles. If you want a globally unique identifier for printed books, then ISBN is a reasonable one to use -- it's not precisely unique (there have been errors assugning the same ISBN to two different books, for example), but it's pretty good for most purposes. If you want an actual globally unique identifier, then some form of UUID would do the job (UUIDv4 is the easiest). Alternatively, you could register a DOI prefix and assign numbers inside your own numberspace within the DOI system. If you want something vaguely human-readable, try dropping all the stop-words (the, a, an, in, on, ...), all the vowels and all the spaces. Truncate at whatever your idea of "short" is. Like the hashing approach, it's not unique in the slightest. It all depends on your use-case. Hugo. -- Hugo Mills | Great films about cricket: Interview with the Umpire hugo@REDACTED carfax.org.uk | http://carfax.org.uk/ | PGP: E2AB1DE4 | From hobson42@REDACTED Fri Aug 13 22:26:15 2021 From: hobson42@REDACTED (Ian Hobson) Date: Fri, 13 Aug 2021 21:26:15 +0100 Subject: Long string to short ID In-Reply-To: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> References: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> Message-ID: <73477604-8913-9da8-51df-8b29c8240a3a@gmail.com> Hi Lloyd On 13/08/2021 20:44, Lloyd R. Prentice wrote: > Hello, > > What might be a nifty way to turn a long book title with spaces into a short human-readable ID? > > Thanks, > > LRP > I can think of two ways. 1) Append the initials of the title (perhaps omitting short functions words like "The", "Of" etc) to the initials of the Author. Also it would help to convert numbers to digits first. "The Four Hour Work Week", by Tim Ferriss becomes TF4HWW Its easy to remember and may even be guessable in context. 2) You could hash the title and express the result in a high base (being careful to avoid confusable letters (I1l, O0 etc), and append that to the Author's initials. So the example might be TFkUw4 This would probably make all the keys a similar length, but would not be guessable. In both cases you will have to have some way to recognise name clashes, and disambiguate them - perhaps adding -1, -2 etc to the duplicates. Regards Ian -- Ian Hobson Tel (+351) 910 418 473 -- This email has been checked for viruses by AVG. https://www.avg.com From lloyd@REDACTED Fri Aug 13 22:34:07 2021 From: lloyd@REDACTED (Lloyd R. prentice) Date: Fri, 13 Aug 2021 16:34:07 -0400 Subject: Long string to short ID In-Reply-To: <20210813201930.GB15870@savella.carfax.org.uk> References: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> <20210813201930.GB15870@savella.carfax.org.uk> Message-ID: <644a5bef-4277-4e4c-bece-bcf71c610f32@www.fastmail.com> Thanks all, Hugo, I like your third idea. I've been thinking about programming a stop word filtering function anyway. Plus, in my use case all of the books are owned by the author so uniqueness is unlikely to be a problem. I can't use ISBNs, since the ids are for books under development. Bit I will definitely use them in other parts of my application. I did program one idea: make_id(String, First, Second) -> List = string:tokens(String, " "), F = lists:nth(First, List), S = lists:nth(Second, List), F ++ "_" ++ S. make_id(String, First) -> List = string:tokens(String, " "), F = lists:nth(First, List), F. It nicely fulfills the short and readable criteria and enables focus on two most significant words in the title, but I can't see a way to automate assignment of values to First and Second. So I played with just selecting the first or first two words in the title. But it makes me uncomfortable. make_id(String) -> List = string:tokens(String, " "), case length(List) > 1 of true -> F = lists:nth(1, List), S = lists:nth(2, List), F ++ "_" ++ S; false -> lists:nth(1, List) end. Best wishes,. Much appreciate the help. LRP On Fri, Aug 13, 2021, at 4:19 PM, Hugo Mills wrote: > On Fri, Aug 13, 2021 at 03:44:29PM -0400, Lloyd R. Prentice wrote: > > Hello, > > > > What might be a nifty way to turn a long book title with spaces into a short human-readable ID? > > Depends rather on what purpose you want to put this ID to. > > One solution would be to hash it (with, say sha256). If the hash is > too long for "short", truncate it. Note that this is not a > globally-unique value, as there are lots of books with identical > titles. > > If you want a globally unique identifier for printed books, then > ISBN is a reasonable one to use -- it's not precisely unique (there > have been errors assugning the same ISBN to two different books, for > example), but it's pretty good for most purposes. > > If you want an actual globally unique identifier, then some form of > UUID would do the job (UUIDv4 is the easiest). Alternatively, you > could register a DOI prefix and assign numbers inside your own > numberspace within the DOI system. > > If you want something vaguely human-readable, try dropping all the > stop-words (the, a, an, in, on, ...), all the vowels and all the > spaces. Truncate at whatever your idea of "short" is. Like the hashing > approach, it's not unique in the slightest. > > It all depends on your use-case. > > Hugo. > > -- > Hugo Mills | Great films about cricket: Interview with the Umpire > hugo@REDACTED carfax.org.uk | > http://carfax.org.uk/ | > PGP: E2AB1DE4 | > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mattevans123@REDACTED Sat Aug 14 01:46:57 2021 From: mattevans123@REDACTED (Matthew Evans) Date: Fri, 13 Aug 2021 23:46:57 +0000 Subject: Long string to short ID In-Reply-To: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> References: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> Message-ID: How about: 1> lists:flatten([integer_to_list(V,16)||<> <= crypto:hash(md5, "really long book title that goes on and on forever")]). "C72BFE8643B0156ACD809D87D51E726C" OR 2> binary_to_list(base64:encode(crypto:hash(md5, "really long book title that goes on and on forever"))). "xyv+hkOwFWrNgJ2H1R5ybA==" ________________________________ From: erlang-questions on behalf of Lloyd R. Prentice Sent: Friday, August 13, 2021 3:44 PM To: erlang-questions Subject: Long string to short ID Hello, What might be a nifty way to turn a long book title with spaces into a short human-readable ID? Thanks, LRP Sent from my iPad -------------- next part -------------- An HTML attachment was scrubbed... URL: From hugo@REDACTED Sat Aug 14 15:00:26 2021 From: hugo@REDACTED (Hugo Mills) Date: Sat, 14 Aug 2021 14:00:26 +0100 Subject: Long string to short ID In-Reply-To: <644a5bef-4277-4e4c-bece-bcf71c610f32@www.fastmail.com> References: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> <20210813201930.GB15870@savella.carfax.org.uk> <644a5bef-4277-4e4c-bece-bcf71c610f32@www.fastmail.com> Message-ID: <20210814130026.GC15870@savella.carfax.org.uk> One thing that strikes me here -- if you want something (only locally unique) that's for the user's consumption, you could probably do a lot worse than simply ask them for an ID. That way, their ID doesn't change when they decide that "Untitled 8" isn't a good title for their book... You probably need to be able to handle a change of title anyway -- if your ID is based on the title, will that change too? If you've asked the user for a short ID, can you change it? (And if not, how will they feel about having "Unttld8" as the ID for their book for ever more?) Hugo. On Fri, Aug 13, 2021 at 04:34:07PM -0400, Lloyd R. prentice wrote: > Thanks all, > > Hugo, I like your third idea. I've been thinking about programming a stop word filtering function anyway. Plus, in my use case all of the books are owned by the author so uniqueness is unlikely to be a problem. > > I can't use ISBNs, since the ids are for books under development. Bit I will definitely use them in other parts of my application. > > I did program one idea: > > make_id(String, First, Second) -> > List = string:tokens(String, " "), > F = lists:nth(First, List), > S = lists:nth(Second, List), > F ++ "_" ++ S. > > make_id(String, First) -> > List = string:tokens(String, " "), > F = lists:nth(First, List), > F. > > It nicely fulfills the short and readable criteria and enables focus on two most significant words in the title, but I can't see a way to automate assignment of values to First and Second. So I played with just selecting the first or first two words in the title. But it makes me uncomfortable. > > make_id(String) -> > List = string:tokens(String, " "), > case length(List) > 1 of > true -> F = lists:nth(1, List), > S = lists:nth(2, List), > F ++ "_" ++ S; > false -> lists:nth(1, List) > end. > > Best wishes,. Much appreciate the help. > > LRP > > > > > > > On Fri, Aug 13, 2021, at 4:19 PM, Hugo Mills wrote: > > On Fri, Aug 13, 2021 at 03:44:29PM -0400, Lloyd R. Prentice wrote: > > > Hello, > > > > > > What might be a nifty way to turn a long book title with spaces into a short human-readable ID? > > > > Depends rather on what purpose you want to put this ID to. > > > > One solution would be to hash it (with, say sha256). If the hash is > > too long for "short", truncate it. Note that this is not a > > globally-unique value, as there are lots of books with identical > > titles. > > > > If you want a globally unique identifier for printed books, then > > ISBN is a reasonable one to use -- it's not precisely unique (there > > have been errors assugning the same ISBN to two different books, for > > example), but it's pretty good for most purposes. > > > > If you want an actual globally unique identifier, then some form of > > UUID would do the job (UUIDv4 is the easiest). Alternatively, you > > could register a DOI prefix and assign numbers inside your own > > numberspace within the DOI system. > > > > If you want something vaguely human-readable, try dropping all the > > stop-words (the, a, an, in, on, ...), all the vowels and all the > > spaces. Truncate at whatever your idea of "short" is. Like the hashing > > approach, it's not unique in the slightest. > > > > It all depends on your use-case. > > > > Hugo. > > -- Hugo Mills | Jenkins! Chap with the wings there! Five rounds hugo@REDACTED carfax.org.uk | rapid! http://carfax.org.uk/ | Brigadier Alistair Lethbridge-Stewart PGP: E2AB1DE4 | Dr Who and the Daemons From empro2@REDACTED Sat Aug 14 16:11:59 2021 From: empro2@REDACTED (Michael P.) Date: Sat, 14 Aug 2021 16:11:59 +0200 Subject: Long string to short ID In-Reply-To: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> References: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> Message-ID: <20210814161159.0c1efb52@aesop> On Fri, 13 Aug 2021 15:44:29 -0400 "Lloyd R. Prentice" wrote: > What might be a nifty way to turn a long book title with spaces into a short human-readable ID? Two observations: Anything too nifty will, sooner or later, put a hole in one's foot. Keeping the beginning helps evoke a context in one's mind in which a following, nifty brixngnaxl may be meaningfully interpreted. Examples: $ ls verse.tex verseses.tex I do not remember what I meant "verseses" to mean. (sounds Gollumic ...) Here I have obviously niftied myself in the foot. $ ls fertig aquestionofmust.tex hinterdg.tex Simple omission of space (and no capitals). + kept head and acronymic tail: hinterdg -> Hinter den Grenzen But it all depends on what ID means here and what is considered "human-readable". And why the title is no human-readable ID, and why a human needs to read any other ID, why the machine cannot map any kind of ID to the title for the human. > focus on two most significant words in the title Significance depends on context even in a single human being; and context depends on time and all the rest of the "situation". See the foot-holing example above. Automating "significance" might require one to wait until androids do not dream of electric sheep anymore ... ~M -- Curiosity killed the cat -- by simply using up its time. From lloyd@REDACTED Sat Aug 14 18:05:27 2021 From: lloyd@REDACTED (Lloyd R. Prentice) Date: Sat, 14 Aug 2021 12:05:27 -0400 Subject: Long string to short ID Message-ID: <8705AC58-2693-45A4-94FF-448F43A2DCFA@writersglen.com> ?Hi Michael, You hint at an interesting line of thought: The question is, why does ?My Long and Fascinating Book Title? feel like such an awkward and inefficient ID in a computer application focusing on books? After all, it is perfectly fine as a signifier of the physical or electronic object in human discourse. So why is it more awkward and inefficient than ?ygjre3*)7x?? when used as an ID in computer code? After all, it would in some sense make the code more readable to humans. Unless I?m missing something, it seems that it?s only more inefficient in the sense that it consumes more memory in RAM and persistent storage and, arguably, processing of the string itself. So, we program some kind of translation layer that associates ?My Long and Fascinating Book Title? with ?ygjre3*)7x?? ? a proplist or some such. Now humans get to consume the literal title and the machine gets the weird, presumably more efficient, string. The question then becomes, how much memory does the translation layer consume and how much latency is involved in the translation process? In other words, how many book titles have to be entered into the system before the costs of the translation layer are amortized? At this point my head hurts, but it seems that there is some application specific number N where less than N books justifies using the book title itself as the ID. Am I missing something? All the best, LRP Sent from my iPad > On Aug 14, 2021, at 10:12 AM, Michael P. wrote: > ?On Fri, 13 Aug 2021 15:44:29 -0400 > "Lloyd R. Prentice" wrote: > >> What might be a nifty way to turn a long book title with spaces into a short human-readable ID? > > Two observations: > > Anything too nifty will, sooner or later, put a hole in one's foot. > > Keeping the beginning helps evoke a context in one's mind in which > a following, nifty brixngnaxl may be meaningfully interpreted. > > Examples: > > $ ls > verse.tex verseses.tex > > I do not remember what I meant "verseses" to mean. (sounds Gollumic ...) > Here I have obviously niftied myself in the foot. > > $ ls fertig > aquestionofmust.tex hinterdg.tex > > Simple omission of space (and no capitals). > + kept head and acronymic tail: hinterdg -> Hinter den Grenzen > > But it all depends on what ID means here > and what is considered "human-readable". > And why the title is no human-readable ID, > and why a human needs to read any other ID, > why the machine cannot map any kind of ID > to the title for the human. > > >> focus on two most significant words in the title > > Significance depends on context even in a single human being; > and context depends on time and all the rest of the "situation". > See the foot-holing example above. > > Automating "significance" might require one to wait until > androids do not dream of electric sheep anymore ... > > > ~M > > -- > > Curiosity killed the cat -- > by simply using up its time. From hugo@REDACTED Sat Aug 14 20:37:28 2021 From: hugo@REDACTED (Hugo Mills) Date: Sat, 14 Aug 2021 19:37:28 +0100 Subject: Long string to short ID In-Reply-To: <8705AC58-2693-45A4-94FF-448F43A2DCFA@writersglen.com> References: <8705AC58-2693-45A4-94FF-448F43A2DCFA@writersglen.com> Message-ID: <20210814183728.GD15870@savella.carfax.org.uk> I think there's a question of the use-case here. Machine-processable IDs (your "ygjre3*)7x?" are generally designed to be *unique* in some way, often *unguessable*, and sometimes *decentralised*. All three of these contraints tend to increase the amount of information the ID needs to contain (i.e. the number of bits it encodes). If you're only worrying about a single author, and don't need unguessable or decentralised, then 8 bits (two hex characters) is sufficient for all except the likes of Isaac Asimov and Barbara Cartland, who would need another couple of bits each. It's fairly easy to come up with schemes that encode those few bits into something readable (say, pick 16 consonants (4 bits) and your favourite 4 vowels (2 bits), and you can produce a generally pronounceable four-letter word with 12 bits of information in it by alternating consonants and vowels). When your scope grows, and your constraints come in, then the IDs need to have more bits, and we tend to throw away readability in favour of compactness, often by things like base-64 encoding, which is 6 bits per character. This generally doesn't matter, because by that point, the IDs are only meant for machines, and the machine can put a nice label on the thing being identified in the user interface. So you get a list of books with their authors, and a button by each book that takes you to the details of that book. Only the machine needs to know that that book is "o34rdh2493fh8" and that clicking the button takes you to the information for "o34rdh2493fh8". All the user knows is that they're seeing "How to Make Long Book Titles and Annoy People" by Joe Q. Author. The translation layer between the two isn't generally going to be a problem -- if it's a small one-user system, then that lookup table is basically lost in the noise. If it's for the whole history of an entire publishing house, then it goes in a database (and is probably still lost in the noise for their whole data storage). Personally, I'd mint a (nearly) guaranteed unique ID like a UUIDv4 from the outset, and use that as a key in all parts of the system to link any information to a book (like, say, its text, or the database of rejection letters). Then never expose that directly to the user in the UI -- although it may leak in the form of web links, say, but those aren't meant to be human readable anyway. That opinion holds regardless of the size of the system. It's possible to get away with funky things like IDs based on the title, provided you've got a small system and you want the users to be reading them, but (a) there's always a bigger user than you expected, and (b) the *users* don't want to be reading your IDs. :) Hugo. On Sat, Aug 14, 2021 at 12:05:27PM -0400, Lloyd R. Prentice wrote: > ?Hi Michael, > > You hint at an interesting line of thought: > > The question is, why does ?My Long and Fascinating Book Title? feel like such an awkward and inefficient ID in a computer application focusing on books? After all, it is perfectly fine as a signifier of the physical or electronic object in human discourse. > > So why is it more awkward and inefficient than ?ygjre3*)7x?? when used as an ID in computer code? After all, it would in some sense make the code more readable to humans. > > Unless I?m missing something, it seems that it?s only more inefficient in the sense that it consumes more memory in RAM and persistent storage and, arguably, processing of the string itself. > > So, we program some kind of translation layer that associates ?My Long and Fascinating Book Title? with ?ygjre3*)7x?? ? a proplist or some such. Now humans get to consume the literal title and the machine gets the weird, presumably more efficient, string. > > The question then becomes, how much memory does the translation layer consume and how much latency is involved in the translation process? In other words, how many book titles have to be entered into the system before the costs of the translation layer are amortized? > > At this point my head hurts, but it seems that there is some application specific number N where less than N books justifies using the book title itself as the ID. > > Am I missing something? > > All the best, > > LRP > > > > > > Sent from my iPad > > > On Aug 14, 2021, at 10:12 AM, Michael P. wrote: > > ?On Fri, 13 Aug 2021 15:44:29 -0400 > > "Lloyd R. Prentice" wrote: > > > >> What might be a nifty way to turn a long book title with spaces into a short human-readable ID? > > > > Two observations: > > > > Anything too nifty will, sooner or later, put a hole in one's foot. > > > > Keeping the beginning helps evoke a context in one's mind in which > > a following, nifty brixngnaxl may be meaningfully interpreted. > > > > Examples: > > > > $ ls > > verse.tex verseses.tex > > > > I do not remember what I meant "verseses" to mean. (sounds Gollumic ...) > > Here I have obviously niftied myself in the foot. > > > > $ ls fertig > > aquestionofmust.tex hinterdg.tex > > > > Simple omission of space (and no capitals). > > + kept head and acronymic tail: hinterdg -> Hinter den Grenzen > > > > But it all depends on what ID means here > > and what is considered "human-readable". > > And why the title is no human-readable ID, > > and why a human needs to read any other ID, > > why the machine cannot map any kind of ID > > to the title for the human. > > > > > >> focus on two most significant words in the title > > > > Significance depends on context even in a single human being; > > and context depends on time and all the rest of the "situation". > > See the foot-holing example above. > > > > Automating "significance" might require one to wait until > > androids do not dream of electric sheep anymore ... > > > > > > ~M > > -- Hugo Mills | Have found Lost City of Atlantis. High Priest is hugo@REDACTED carfax.org.uk | winning at quoits. http://carfax.org.uk/ | PGP: E2AB1DE4 | Terry Pratchett From lloyd@REDACTED Sat Aug 14 21:32:56 2021 From: lloyd@REDACTED (Lloyd R. Prentice) Date: Sat, 14 Aug 2021 15:32:56 -0400 Subject: Long string to short ID In-Reply-To: <20210814183728.GD15870@savella.carfax.org.uk> References: <20210814183728.GD15870@savella.carfax.org.uk> Message-ID: <823C0925-1D03-49AB-939D-1D614E2B2761@writersglen.com> Hi Hugo, It?s interesting how what from a distance looks like a detail is fraught with deep implications. When dealing with book titles we have think about all you?ve suggested as well as how we?ll represent them as file names. I?m preserving your post in my lab notes file. You and others have given me much to consider and I?m vastly grateful. I?m almost finished with the stop-word filter we discussed back a bit. Happy to share the code with anyone interested and, certainly, learn from critiques. All the best, LRP Sent from my iPad > On Aug 14, 2021, at 2:38 PM, Hugo Mills wrote: > > ? I think there's a question of the use-case here. > Machine-processable IDs (your "ygjre3*)7x?" are generally designed to > be *unique* in some way, often *unguessable*, and sometimes > *decentralised*. All three of these contraints tend to increase the > amount of information the ID needs to contain (i.e. the number of bits > it encodes). If you're only worrying about a single author, and don't > need unguessable or decentralised, then 8 bits (two hex characters) is > sufficient for all except the likes of Isaac Asimov and Barbara > Cartland, who would need another couple of bits each. It's fairly easy > to come up with schemes that encode those few bits into something > readable (say, pick 16 consonants (4 bits) and your favourite 4 vowels > (2 bits), and you can produce a generally pronounceable four-letter > word with 12 bits of information in it by alternating consonants and > vowels). > > When your scope grows, and your constraints come in, then the IDs > need to have more bits, and we tend to throw away readability in > favour of compactness, often by things like base-64 encoding, which is > 6 bits per character. This generally doesn't matter, because by that > point, the IDs are only meant for machines, and the machine can put a > nice label on the thing being identified in the user interface. So you > get a list of books with their authors, and a button by each book that > takes you to the details of that book. Only the machine needs to know > that that book is "o34rdh2493fh8" and that clicking the button takes > you to the information for "o34rdh2493fh8". All the user knows is that > they're seeing "How to Make Long Book Titles and Annoy People" by Joe > Q. Author. > > The translation layer between the two isn't generally going to be a > problem -- if it's a small one-user system, then that lookup table is > basically lost in the noise. If it's for the whole history of an > entire publishing house, then it goes in a database (and is probably > still lost in the noise for their whole data storage). > > Personally, I'd mint a (nearly) guaranteed unique ID like a UUIDv4 > from the outset, and use that as a key in all parts of the system to > link any information to a book (like, say, its text, or the database > of rejection letters). Then never expose that directly to the user in > the UI -- although it may leak in the form of web links, say, but > those aren't meant to be human readable anyway. > > That opinion holds regardless of the size of the system. It's > possible to get away with funky things like IDs based on the title, > provided you've got a small system and you want the users to be > reading them, but (a) there's always a bigger user than you expected, > and (b) the *users* don't want to be reading your IDs. :) > > Hugo. > >> On Sat, Aug 14, 2021 at 12:05:27PM -0400, Lloyd R. Prentice wrote: >> ?Hi Michael, >> >> You hint at an interesting line of thought: >> >> The question is, why does ?My Long and Fascinating Book Title? feel like such an awkward and inefficient ID in a computer application focusing on books? After all, it is perfectly fine as a signifier of the physical or electronic object in human discourse. >> >> So why is it more awkward and inefficient than ?ygjre3*)7x?? when used as an ID in computer code? After all, it would in some sense make the code more readable to humans. >> >> Unless I?m missing something, it seems that it?s only more inefficient in the sense that it consumes more memory in RAM and persistent storage and, arguably, processing of the string itself. >> >> So, we program some kind of translation layer that associates ?My Long and Fascinating Book Title? with ?ygjre3*)7x?? ? a proplist or some such. Now humans get to consume the literal title and the machine gets the weird, presumably more efficient, string. >> >> The question then becomes, how much memory does the translation layer consume and how much latency is involved in the translation process? In other words, how many book titles have to be entered into the system before the costs of the translation layer are amortized? >> >> At this point my head hurts, but it seems that there is some application specific number N where less than N books justifies using the book title itself as the ID. >> >> Am I missing something? >> >> All the best, >> >> LRP >> >> >> >> >> >> Sent from my iPad >> >>>> On Aug 14, 2021, at 10:12 AM, Michael P. wrote: >>> ?On Fri, 13 Aug 2021 15:44:29 -0400 >>> "Lloyd R. Prentice" wrote: >>> >>>> What might be a nifty way to turn a long book title with spaces into a short human-readable ID? >>> >>> Two observations: >>> >>> Anything too nifty will, sooner or later, put a hole in one's foot. >>> >>> Keeping the beginning helps evoke a context in one's mind in which >>> a following, nifty brixngnaxl may be meaningfully interpreted. >>> >>> Examples: >>> >>> $ ls >>> verse.tex verseses.tex >>> >>> I do not remember what I meant "verseses" to mean. (sounds Gollumic ...) >>> Here I have obviously niftied myself in the foot. >>> >>> $ ls fertig >>> aquestionofmust.tex hinterdg.tex >>> >>> Simple omission of space (and no capitals). >>> + kept head and acronymic tail: hinterdg -> Hinter den Grenzen >>> >>> But it all depends on what ID means here >>> and what is considered "human-readable". >>> And why the title is no human-readable ID, >>> and why a human needs to read any other ID, >>> why the machine cannot map any kind of ID >>> to the title for the human. >>> >>> >>>> focus on two most significant words in the title >>> >>> Significance depends on context even in a single human being; >>> and context depends on time and all the rest of the "situation". >>> See the foot-holing example above. >>> >>> Automating "significance" might require one to wait until >>> androids do not dream of electric sheep anymore ... >>> >>> >>> ~M >>> > > -- > Hugo Mills | Have found Lost City of Atlantis. High Priest is > hugo@REDACTED carfax.org.uk | winning at quoits. > http://carfax.org.uk/ | > PGP: E2AB1DE4 | Terry Pratchett From hugo@REDACTED Sat Aug 14 21:37:20 2021 From: hugo@REDACTED (Hugo Mills) Date: Sat, 14 Aug 2021 20:37:20 +0100 Subject: Long string to short ID In-Reply-To: <823C0925-1D03-49AB-939D-1D614E2B2761@writersglen.com> References: <20210814183728.GD15870@savella.carfax.org.uk> <823C0925-1D03-49AB-939D-1D614E2B2761@writersglen.com> Message-ID: <20210814193720.GE15870@savella.carfax.org.uk> I'm an ontologist & knowledge engineer in my day job, so IDs are one of the things that I have to think about professionally. :) Glad you find the discussion useful. Hugo. On Sat, Aug 14, 2021 at 03:32:56PM -0400, Lloyd R. Prentice wrote: > Hi Hugo, > > It?s interesting how what from a distance looks like a detail is fraught with deep implications. When dealing with book titles we have think about all you?ve suggested as well as how we?ll represent them as file names. > > I?m preserving your post in my lab notes file. > > You and others have given me much to consider and I?m vastly grateful. > > I?m almost finished with the stop-word filter we discussed back a bit. Happy to share the code with anyone interested and, certainly, learn from critiques. > > All the best, > > LRP > > Sent from my iPad > > > On Aug 14, 2021, at 2:38 PM, Hugo Mills wrote: > > > > ? I think there's a question of the use-case here. > > Machine-processable IDs (your "ygjre3*)7x?" are generally designed to > > be *unique* in some way, often *unguessable*, and sometimes > > *decentralised*. All three of these contraints tend to increase the > > amount of information the ID needs to contain (i.e. the number of bits > > it encodes). If you're only worrying about a single author, and don't > > need unguessable or decentralised, then 8 bits (two hex characters) is > > sufficient for all except the likes of Isaac Asimov and Barbara > > Cartland, who would need another couple of bits each. It's fairly easy > > to come up with schemes that encode those few bits into something > > readable (say, pick 16 consonants (4 bits) and your favourite 4 vowels > > (2 bits), and you can produce a generally pronounceable four-letter > > word with 12 bits of information in it by alternating consonants and > > vowels). > > > > When your scope grows, and your constraints come in, then the IDs > > need to have more bits, and we tend to throw away readability in > > favour of compactness, often by things like base-64 encoding, which is > > 6 bits per character. This generally doesn't matter, because by that > > point, the IDs are only meant for machines, and the machine can put a > > nice label on the thing being identified in the user interface. So you > > get a list of books with their authors, and a button by each book that > > takes you to the details of that book. Only the machine needs to know > > that that book is "o34rdh2493fh8" and that clicking the button takes > > you to the information for "o34rdh2493fh8". All the user knows is that > > they're seeing "How to Make Long Book Titles and Annoy People" by Joe > > Q. Author. > > > > The translation layer between the two isn't generally going to be a > > problem -- if it's a small one-user system, then that lookup table is > > basically lost in the noise. If it's for the whole history of an > > entire publishing house, then it goes in a database (and is probably > > still lost in the noise for their whole data storage). > > > > Personally, I'd mint a (nearly) guaranteed unique ID like a UUIDv4 > > from the outset, and use that as a key in all parts of the system to > > link any information to a book (like, say, its text, or the database > > of rejection letters). Then never expose that directly to the user in > > the UI -- although it may leak in the form of web links, say, but > > those aren't meant to be human readable anyway. > > > > That opinion holds regardless of the size of the system. It's > > possible to get away with funky things like IDs based on the title, > > provided you've got a small system and you want the users to be > > reading them, but (a) there's always a bigger user than you expected, > > and (b) the *users* don't want to be reading your IDs. :) > > > > Hugo. > > > >> On Sat, Aug 14, 2021 at 12:05:27PM -0400, Lloyd R. Prentice wrote: > >> ?Hi Michael, > >> > >> You hint at an interesting line of thought: > >> > >> The question is, why does ?My Long and Fascinating Book Title? feel like such an awkward and inefficient ID in a computer application focusing on books? After all, it is perfectly fine as a signifier of the physical or electronic object in human discourse. > >> > >> So why is it more awkward and inefficient than ?ygjre3*)7x?? when used as an ID in computer code? After all, it would in some sense make the code more readable to humans. > >> > >> Unless I?m missing something, it seems that it?s only more inefficient in the sense that it consumes more memory in RAM and persistent storage and, arguably, processing of the string itself. > >> > >> So, we program some kind of translation layer that associates ?My Long and Fascinating Book Title? with ?ygjre3*)7x?? ? a proplist or some such. Now humans get to consume the literal title and the machine gets the weird, presumably more efficient, string. > >> > >> The question then becomes, how much memory does the translation layer consume and how much latency is involved in the translation process? In other words, how many book titles have to be entered into the system before the costs of the translation layer are amortized? > >> > >> At this point my head hurts, but it seems that there is some application specific number N where less than N books justifies using the book title itself as the ID. > >> > >> Am I missing something? > >> > >> All the best, > >> > >> LRP > >> > >> > >> > >> > >> > >> Sent from my iPad > >> > >>>> On Aug 14, 2021, at 10:12 AM, Michael P. wrote: > >>> ?On Fri, 13 Aug 2021 15:44:29 -0400 > >>> "Lloyd R. Prentice" wrote: > >>> > >>>> What might be a nifty way to turn a long book title with spaces into a short human-readable ID? > >>> > >>> Two observations: > >>> > >>> Anything too nifty will, sooner or later, put a hole in one's foot. > >>> > >>> Keeping the beginning helps evoke a context in one's mind in which > >>> a following, nifty brixngnaxl may be meaningfully interpreted. > >>> > >>> Examples: > >>> > >>> $ ls > >>> verse.tex verseses.tex > >>> > >>> I do not remember what I meant "verseses" to mean. (sounds Gollumic ...) > >>> Here I have obviously niftied myself in the foot. > >>> > >>> $ ls fertig > >>> aquestionofmust.tex hinterdg.tex > >>> > >>> Simple omission of space (and no capitals). > >>> + kept head and acronymic tail: hinterdg -> Hinter den Grenzen > >>> > >>> But it all depends on what ID means here > >>> and what is considered "human-readable". > >>> And why the title is no human-readable ID, > >>> and why a human needs to read any other ID, > >>> why the machine cannot map any kind of ID > >>> to the title for the human. > >>> > >>> > >>>> focus on two most significant words in the title > >>> > >>> Significance depends on context even in a single human being; > >>> and context depends on time and all the rest of the "situation". > >>> See the foot-holing example above. > >>> > >>> Automating "significance" might require one to wait until > >>> androids do not dream of electric sheep anymore ... > >>> > >>> > >>> ~M > >>> > > -- Hugo Mills | I'm on a 30-day diet. So far I've lost 18 days. hugo@REDACTED carfax.org.uk | http://carfax.org.uk/ | PGP: E2AB1DE4 | From empro2@REDACTED Sat Aug 14 23:28:58 2021 From: empro2@REDACTED (Michael P.) Date: Sat, 14 Aug 2021 23:28:58 +0200 Subject: Long string to short ID In-Reply-To: <8705AC58-2693-45A4-94FF-448F43A2DCFA@writersglen.com> References: <8705AC58-2693-45A4-94FF-448F43A2DCFA@writersglen.com> Message-ID: <20210814232858.1217f585@aesop> On Sat, 14 Aug 2021 12:05:27 -0400 "Lloyd R. Prentice" wrote: > The question is, why does ?My Long and Fascinating Book Title? feel like such an awkward and inefficient ID in a computer application focusing on books? Because it is not an ID, not for the computer? My brain-executed flexi-algo filenames _are_no_IDs_, for no programming language and no file-system; they are merely some human-readable (hopefully) "alternative titles". Or do you want to do something like One = 1, X = 10, MCL = 1150, -define(Rmb_3, "Rambo 3"), ... -define(Rmb_3, "Rambo 385") % significance error included create a programming language identifier for every domain value? That would be like confusing parameter and argument. > So, we program some kind of translation layer that associates ?My Long and Fascinating Book Title? with ?ygjre3*)7x?? ? a proplist or some such. Now humans get to consume the literal title and the machine gets the weird, presumably more efficient, string. Or simply some integer. Here are some lines I deleted from my previous message: next_id() -> Next = last_id() + 1, store_id(Next), Next. ... The_book = #{title => "endless sermonic book title XXVIII", author => "S/O", ... ... store_book(next_id(), The_book) > The question then becomes, how much memory does the translation layer consume and how much latency is involved in the translation process? When you use Erlang and atoms, then you use some such translation process ... compile-timey ... run-timey when you print atoms and list_to_known_atom() and ... better not. Any translation from any however shortened "human readable ID" to the full "title" performed by the fuzzy-logic pudding in some human's head is slower and more prone to error. And if you want to algorithmically create _alternative_titles_: any shortening algo will be relentlessly executed by the machine, and prone to errors even when the machine is "right". The FAT32 filename truncation algo will explode after Z~999999, or such. And it does not care about "human readable" ... ... apart from "keeping the head" ... to some extent ... ~M -- To err is human, To error machine. From empro2@REDACTED Sat Aug 14 23:44:58 2021 From: empro2@REDACTED (Michael P.) Date: Sat, 14 Aug 2021 23:44:58 +0200 Subject: Why do some people shun `if`? Message-ID: <20210814234458.7c1c9ceb@aesop> I once stumbled over someone's Erlang style guide, they wanted no `if`. It was not very well explained why, and there was no obvious e-mail address, or I wanted to first do some thorough thinking about it. Now I have no more than this: Is if not merely "syntactic sugar" for a fun/0 with guarded clauses? ``` Now_this_is = (fun If() when Guard_seq_1 -> Expr_seq_1 %% On and on and on ; If() when Guard_seq_N -> Expr_seq_N end)(), % or: Worst = case true of true when Guard_seq_1 -> Expr_seq_1 ; true when Guard_seq_2 -> Expr_seq_2 end. ``` What could be perceived as wrong with `if`? ~M -- But who will test the tests? From empro2@REDACTED Sun Aug 15 00:27:34 2021 From: empro2@REDACTED (Michael P.) Date: Sun, 15 Aug 2021 00:27:34 +0200 Subject: Why, for example, maps but array? Message-ID: <20210815002734.3f358965@aesop> When writing Erlang, my brain always produces: array, filename, list, map, ..., but not: lists, maps, proplists, sets, .... I cannot imagine that anyone applies the general concept of 'module deals with lists' to writing a concrete line of source code. To me `+` is 'addition', not 'additions'. There is even orddict but ordsets ... ... that corresponds to dict but sets. The decision seems to depend on author and some tossing of coins. Can there be learned anything from that? ~Michael -- The story of the Ministry of funny Operators: := new walrus ;= winking walrus ?:= confused walrus :,= weeping walrus X= extinct walrus From lloyd@REDACTED Sun Aug 15 00:42:40 2021 From: lloyd@REDACTED (Lloyd R. Prentice) Date: Sat, 14 Aug 2021 18:42:40 -0400 Subject: Why, for example, maps but array? In-Reply-To: <20210815002734.3f358965@aesop> References: <20210815002734.3f358965@aesop> Message-ID: Hi Michael, I just used sets today to write a search tag generator. Works. But it surprises me that obvious functions like file:move/2 and the a write companion to file:consult/1 are not in the library. No doubt someone has an explanation. Today I wanted to pull a list of search words out of a file and turn the list into a function. I?m sure it?s simple but beyond my pay grade. Somewhat confused that some file functions require filenames and others IoDevice. Re if constructions, I turn first to pattern matching, next to case statements. But I suspect there?s a cogent discussion buried in the Erlang archives. I?m a dilettante, but hack on with purpose. Best, LRP Sent from my iPad > On Aug 14, 2021, at 6:27 PM, Michael P. wrote: > > ?When writing Erlang, my brain always produces: > array, filename, list, map, ..., but not: > lists, maps, proplists, sets, .... > > I cannot imagine that anyone applies the > general concept of 'module deals with lists' > to writing a concrete line of source code. > > To me `+` is 'addition', not 'additions'. > > There is even orddict but ordsets ... > > ... that corresponds to dict but sets. > > The decision seems to depend on author > and some tossing of coins. > > Can there be learned anything from that? > > > ~Michael > > -- > > The story of the Ministry of funny Operators: > > := new walrus > ;= winking walrus > ?:= confused walrus > :,= weeping walrus > X= extinct walrus > > > > > > From raould@REDACTED Sun Aug 15 01:09:44 2021 From: raould@REDACTED (Raoul Duke) Date: Sat, 14 Aug 2021 16:09:44 -0700 Subject: Why, for example, maps but array? In-Reply-To: References: <20210815002734.3f358965@aesop> Message-ID: i suspect as with many such things, "because history." :-) From free7by@REDACTED Sun Aug 15 05:00:01 2021 From: free7by@REDACTED (Yao Bao) Date: Sun, 15 Aug 2021 11:00:01 +0800 Subject: Long string to short ID In-Reply-To: <20210814232858.1217f585@aesop> References: <20210814232858.1217f585@aesop> Message-ID: <6A882035-51C5-489F-A553-687E91D016CB@163.com> Hello, I think the problem comes from the fundamental differences between our physical world and computing world. We do copy things in both worlds. In computing world, two copies are really identical, but this is not true in physical world. Two physical copies of one book are different, they are the same for humans (we think so), but the fact is the opposite. How about taking the book title or even the book content as an atom (suppose we have unlimited storage...)? Then they might become unique, a little bit like our physical copies. Well, strictly speaking, the are not, we haven?t count the time yet... How to uniquely reference or finding things is extremely difficult, we have to have some precision losing in computing world though. So we have things like GUID in general or reference in Erlang. Cheers, Yao From zxq9@REDACTED Sun Aug 15 06:48:39 2021 From: zxq9@REDACTED (zxq9) Date: Sun, 15 Aug 2021 13:48:39 +0900 Subject: Why do some people shun `if`? In-Reply-To: <20210814234458.7c1c9ceb@aesop> References: <20210814234458.7c1c9ceb@aesop> Message-ID: <6b2bd4e6-df24-e7ac-93a1-248a220b755b@zxq9.com> Hi, Michael. On 2021/08/15 6:44, Michael P. wrote: > I once stumbled over someone's Erlang style guide, > they wanted no `if`. > It was not very well explained why, ... > Is if not merely "syntactic sugar" for > a fun/0 with guarded clauses? The main reason people dislike `if` is that it applies to boolean comparison situations where `case` provides for a much more interesting semantic for branching. `if` is most often best used in situations where you have a *range* of values you want to completely cover: if X > Y -> do_something(); X = Y -> do_something_else(); Y < Y -> do_yet_another_thing() end This is *not* the same as a simpler boolean case case X > Y of true -> foo(); false -> bar() end `if` enables more complex ranges and the drop-through nature of the various clauses are occasionally very useful in reducing some evaluation of complex checks that tend to create even messier and more complex code to something easy to read. You can still always do the same thing with a `case` using guards, though -- and as you mentioned you *could* do the same with funs, but that's a bit crazy as you're invoking the lambda machinery for really no reason as there is motivation to create and execute a function in place when you just want to perform a simple comparison. In Erlang it is much more common to use `case` for just about everything and most programs don't have a single `if` in them at all unless they are written by people coming to Erlang from another language that only has `if` (and then they wind up often misunderstanding the semantics of Erlang's version of `if`, so you see the default `true` clause pop up, which makes the newcomer think "this is silly, why does Erlang's `if` work this way?" because using `if` that was *is* silly in most cases). Anyway... generally speaking `case` is much more powerful than `if`, and `if` has a very niche use case for which it is a very concise way of doing comparisons within a function body that carries some context you need to involve in the `if` test clauses that would otherwise be cumbersome to pass along to a special function whose only job was to check something in guards. -Craig From zxq9@REDACTED Sun Aug 15 06:57:42 2021 From: zxq9@REDACTED (zxq9) Date: Sun, 15 Aug 2021 13:57:42 +0900 Subject: Why, for example, maps but array? In-Reply-To: References: <20210815002734.3f358965@aesop> Message-ID: On 2021/08/15 7:42, Lloyd R. Prentice wrote: > I just used sets today to write a search tag generator. Works. But it surprises me that obvious functions like file:move/2 and the a write companion to file:consult/1 are not in the library. No doubt someone has an explanation. Indeed! https://zxq9.com/archives/1021 > Re if constructions, I turn first to pattern matching, next to case statements. But I suspect there?s a cogent discussion buried in the Erlang archives. There is and I've written about it a bit but have no idea where it is in the archives -- search engines are not finding it. >> On Aug 14, 2021, at 6:27 PM, Michael P. wrote: >> I cannot imagine that anyone applies the >> general concept of 'module deals with lists' >> to writing a concrete line of source code. >> >> To me `+` is 'addition', not 'additions'. There is something to this... >> The decision seems to depend on author >> and some tossing of coins. ...and this as well. There are few different things going on. One layer is the semantic choice of "does the name of this module indicate that this modules 'deals with Xs' or does it represent *a* single X when the user is typing it?" Another layer is the tradition of functional languages having lots of listy and collectiony data structures and writing functions and modules to do things over them as collections instead of individual elements. I like it when the naming semantic for the interface module to an X is singular. It makes sense to me as a user of that module to say `map:find(Key, Map)` rather than `maps:find(Key, Map)`, but also makes sense to have a separate module called actually `maps` for things like the "List of Maps" module that I wrote a while back that was recently discussed as a possible candidate for inclusion in the stdlib (though probably under a different name). https://gitlab.com/zxq9/lom These semantic sort of things are quirks and no guideline for formalizing them has been fleshed out. Argument order regularity is also a bit of a crap shoot throughout the stdlib, but over time you sort of learn it and stop caring. Fixing this stuff up would be cool, but takes a huge amount of effort that is a bit hard to muster for such a small community with zero funding. -Craig From ulf@REDACTED Sun Aug 15 09:36:33 2021 From: ulf@REDACTED (Ulf Wiger) Date: Sun, 15 Aug 2021 09:36:33 +0200 Subject: Why do some people shun `if`? In-Reply-To: <6b2bd4e6-df24-e7ac-93a1-248a220b755b@zxq9.com> References: <20210814234458.7c1c9ceb@aesop> <6b2bd4e6-df24-e7ac-93a1-248a220b755b@zxq9.com> Message-ID: After having worked with really complex systems in very large projects, I've come to appreciate syntactic constructs signaling that nothing bad can ever happen there. As Craig points out, 'case' is much more flexible, but this also potentially means that the expression evaluated by the case clause could contain gremlins. In an 'if' clause, only guard expressions are allowed, so only pure pattern matching - no side-effects allowed. I think that's worth something. BR, Ulf On Sun, Aug 15, 2021 at 6:48 AM zxq9 wrote: > Hi, Michael. > > On 2021/08/15 6:44, Michael P. wrote: > > I once stumbled over someone's Erlang style guide, > > they wanted no `if`. > > It was not very well explained why, > ... > > Is if not merely "syntactic sugar" for > > a fun/0 with guarded clauses? > > The main reason people dislike `if` is that it applies to boolean > comparison situations where `case` provides for a much more interesting > semantic for branching. `if` is most often best used in situations where > you have a *range* of values you want to completely cover: > > if > X > Y -> do_something(); > X = Y -> do_something_else(); > Y < Y -> do_yet_another_thing() > end > > This is *not* the same as a simpler boolean case > > case X > Y of > true -> foo(); > false -> bar() > end > > `if` enables more complex ranges and the drop-through nature of the > various clauses are occasionally very useful in reducing some evaluation > of complex checks that tend to create even messier and more complex code > to something easy to read. > > You can still always do the same thing with a `case` using guards, > though -- and as you mentioned you *could* do the same with funs, but > that's a bit crazy as you're invoking the lambda machinery for really no > reason as there is motivation to create and execute a function in place > when you just want to perform a simple comparison. > > In Erlang it is much more common to use `case` for just about everything > and most programs don't have a single `if` in them at all unless they > are written by people coming to Erlang from another language that only > has `if` (and then they wind up often misunderstanding the semantics of > Erlang's version of `if`, so you see the default `true` clause pop up, > which makes the newcomer think "this is silly, why does Erlang's `if` > work this way?" because using `if` that was *is* silly in most cases). > > Anyway... generally speaking `case` is much more powerful than `if`, and > `if` has a very niche use case for which it is a very concise way of > doing comparisons within a function body that carries some context you > need to involve in the `if` test clauses that would otherwise be > cumbersome to pass along to a special function whose only job was to > check something in guards. > > -Craig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jesper.louis.andersen@REDACTED Sun Aug 15 15:15:02 2021 From: jesper.louis.andersen@REDACTED (Jesper Louis Andersen) Date: Sun, 15 Aug 2021 15:15:02 +0200 Subject: Why do some people shun `if`? In-Reply-To: <20210814234458.7c1c9ceb@aesop> References: <20210814234458.7c1c9ceb@aesop> Message-ID: On Sat, Aug 14, 2021 at 11:45 PM Michael P. wrote: > I once stumbled over someone's Erlang style guide, > they wanted no `if`. > > There are uses for the if...end construct in Erlang. The reason you often shun it is because it occurs quite rarely in a language where you have a proper case...end matching construct. So to avoid newcomers to fall into a trap of using if all the time, you write it down in the style guide. In reality, style can be broken for improved readability, but it takes some knowledge to know exactly when. The deeper underlying problem is that of "boolean blindness". A value that is true/false doesn't tell you *why*. If you write a function such as empty([]) -> true; empty([_|_]) -> false. you know that the list is empty, but you don't get to know it's structure. Whereas with a match case L of [] -> ...; [H|T] -> ... end, you *do* know the structure in each variant clause, and you also have convenient bindings for the head and tail. If-constructs will have you analyze the structure after you hit a branch, whereas pattern matching allows you to make that analysis up front. Erlang terms are ripe for scrutiny, so as a result, you'll find much more use of case than if. That said, and what Ulf alludes to: there are always exceptions to the rule. -------------- next part -------------- An HTML attachment was scrubbed... URL: From zxq9@REDACTED Sun Aug 15 15:20:49 2021 From: zxq9@REDACTED (zxq9) Date: Sun, 15 Aug 2021 22:20:49 +0900 Subject: Why do some people shun `if`? In-Reply-To: References: <20210814234458.7c1c9ceb@aesop> Message-ID: <239b094a-7574-ec51-b011-bc7074aa73fc@zxq9.com> On 2021/08/15 22:15, Jesper Louis Andersen wrote: > There are uses for the if...end construct in Erlang. The reason you > often shun it is because it occurs quite rarely in a language where you > have a proper case...end matching construct. So to avoid newcomers to > fall into a trap of using if all the time, you write it down in the > style guide. This sentence, generalized, should be in ever style guide for every language -- and not just for `if` vs proper `case`. I don't have time to expand on the intuition this triggered, but it is a really great expression. Thanks, Jesper! -Craig From scherrey@REDACTED Sun Aug 15 11:28:55 2021 From: scherrey@REDACTED (Benjamin Scherrey) Date: Sun, 15 Aug 2021 16:28:55 +0700 Subject: Why do some people shun `if`? In-Reply-To: <20210814234458.7c1c9ceb@aesop> References: <20210814234458.7c1c9ceb@aesop> Message-ID: Good question. It turns out that abuses of 'if' as flow control, especially synchronized flow control, is the single largest cause of defects in software development for all time. In fact, a strong case can be made (and is made in this outstanding video ( https://youtu.be/z43bmaMwagI ) that 'goto' was the fall guy for 'if' in Dykstra's famous letter to the ACM. Mainly the issue is the use of 'if' as a statement for alternative program control flow more than using 'if' as an expression (as is typically the case in Erlang). It generally manifests itself in imperative languages and you see it much improved in languages that provide better structural flow controls like pattern matching and aspects typical of functional languages, again like what Erlang offers. In all my coding I restrain 'if' to assertions or guards that are either immediately passed so the program continues having passed a logic filter and never use it to decide amongst two (or more) alternative flow paths within the same code block/function. In Erlang I only use 'if' as guard statements (and prefer 'when'). It makes me far more confident in the quality of my code when I have no 'if' statements at all. - - Ben Scherrey On Sun, Aug 15, 2021, 4:45 AM Michael P. wrote: > I once stumbled over someone's Erlang style guide, > they wanted no `if`. > It was not very well explained why, > and there was no obvious e-mail address, > or I wanted to first do > some thorough thinking about it. > Now I have no more than this: > > Is if not merely "syntactic sugar" for > a fun/0 with guarded clauses? > ``` > Now_this_is = (fun If() when Guard_seq_1 -> Expr_seq_1 > %% On and on and on > ; If() when Guard_seq_N -> Expr_seq_N > end)(), > % or: > Worst = case true > of true when Guard_seq_1 -> Expr_seq_1 > ; true when Guard_seq_2 -> Expr_seq_2 > end. > ``` > What could be perceived as wrong with `if`? > > ~M > > -- > > But who will test the tests? > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lloyd@REDACTED Sun Aug 15 16:30:21 2021 From: lloyd@REDACTED (Lloyd R. Prentice) Date: Sun, 15 Aug 2021 10:30:21 -0400 Subject: Why, for example, maps but array? In-Reply-To: <135BD767-183A-4549-ADCC-D2AE1295E76E@niemier.pl> References: <135BD767-183A-4549-ADCC-D2AE1295E76E@niemier.pl> Message-ID: Ah, thank you, ?ukasz, Got it. All the best, LRP Sent from my iPad > On Aug 15, 2021, at 5:21 AM, ?ukasz Niemier wrote: > > ? >> >> But it surprises me that obvious functions like file:move/2 > > The problem is that such function is far from "obvious". If you look through many languages you will see, that rarely there is `move` function that moves the file from one location to another. Reason for that is simple - UNIX (I do not know how about Windows) do not have such function, instead there is `rename` function which indeed is present in Erlang [1]. That function has one great limitation - it works **only within single filesystem**. If you want to move file between different filesystems, then it will fail. > > - But, there is `mv` command in shell. > > You may ask. Yes, there is such command, but it operates in 2 different ways, depending on the locations of the files: > > - If source and destination is on the same filesystem, then it just call `rename` and call it a day. > - If source and destination is on different filesystems, then it reads source file, writes it in the destination (aka, does a copy of that file) and then removes the source. > > So reasons for non-existence of `file:move/2` in Erlang is law of leaky abstractions. Nothing more, nothing less. > > [1]: https://erlang.org/doc/man/file.html#rename-2 > > -- > > ?ukasz Niemier > lukasz@REDACTED > From raoknz@REDACTED Mon Aug 16 03:38:02 2021 From: raoknz@REDACTED (Richard O'Keefe) Date: Mon, 16 Aug 2021 13:38:02 +1200 Subject: Why, for example, maps but array? In-Reply-To: References: <135BD767-183A-4549-ADCC-D2AE1295E76E@niemier.pl> Message-ID: There is also the question of the semantics of "moving" a file. If I open X for reading, Y for writing, copy contents of X to Y, close both, and delete X, have I "moved" X? In a file system with attributes (BeOS, NTFS, macOS, Linux), the answer is NO, I have moved the *contents* of the file, but the *attributes* have been lost. In Linux at least, it isn't *possible* for a process without certain capabilities to copy *all* the attributes of a file. Copying a file from one file system to another may run into problems. For example, some Linux file systems impose no limit on the total size of attributes, but others require them to all fit in a single block. Let's not get into the issues of copying between file systems with *different* attribute systems, difference attribute namespaces &c. Did I mention access control lists (ACLs)? I set out to provide an interface to ACLs once, only to discover that the operating systems I wanted this to work on had very very little in common. What does it mean to "move" a file to a file system from another machine with a different set of users? Honestly, the deeper I look into *any* operating system issue the more I dread woodpeckers [%]. [%] "If builders built buildings the way programmers write programs, the first woodpecker that came along would destroy civilization." -- Weinberg's second law. On Mon, 16 Aug 2021 at 02:30, Lloyd R. Prentice wrote: > > Ah, thank you, ?ukasz, > > Got it. > > All the best, > > LRP > > Sent from my iPad > > > On Aug 15, 2021, at 5:21 AM, ?ukasz Niemier wrote: > > > > ? > >> > >> But it surprises me that obvious functions like file:move/2 > > > > The problem is that such function is far from "obvious". If you look through many languages you will see, that rarely there is `move` function that moves the file from one location to another. Reason for that is simple - UNIX (I do not know how about Windows) do not have such function, instead there is `rename` function which indeed is present in Erlang [1]. That function has one great limitation - it works **only within single filesystem**. If you want to move file between different filesystems, then it will fail. > > > > - But, there is `mv` command in shell. > > > > You may ask. Yes, there is such command, but it operates in 2 different ways, depending on the locations of the files: > > > > - If source and destination is on the same filesystem, then it just call `rename` and call it a day. > > - If source and destination is on different filesystems, then it reads source file, writes it in the destination (aka, does a copy of that file) and then removes the source. > > > > So reasons for non-existence of `file:move/2` in Erlang is law of leaky abstractions. Nothing more, nothing less. > > > > [1]: https://erlang.org/doc/man/file.html#rename-2 > > > > -- > > > > ?ukasz Niemier > > lukasz@REDACTED > > > From raoknz@REDACTED Mon Aug 16 09:01:33 2021 From: raoknz@REDACTED (Richard O'Keefe) Date: Mon, 16 Aug 2021 19:01:33 +1200 Subject: Why do some people shun `if`? In-Reply-To: <20210814234458.7c1c9ceb@aesop> References: <20210814234458.7c1c9ceb@aesop> Message-ID: My reason for avoiding "if" in Erlang is that it doesn't do what I expect, so I am likely to get it wrong. From using many many other programming languages, I expect 'if ', but in Erlang it's 'if '. To add to the confusion, instead of separating guards and expressions even more clearly, Erlang has blurred them further. So sometimes making that mistake will have no consequences, and other times it will make me sorry. It's one of those things like writing == instead of == in C, to avoid the error of writing = instead of ==. On Sun, 15 Aug 2021 at 09:45, Michael P. wrote: > > I once stumbled over someone's Erlang style guide, > they wanted no `if`. > It was not very well explained why, > and there was no obvious e-mail address, > or I wanted to first do > some thorough thinking about it. > Now I have no more than this: > > Is if not merely "syntactic sugar" for > a fun/0 with guarded clauses? > ``` > Now_this_is = (fun If() when Guard_seq_1 -> Expr_seq_1 > %% On and on and on > ; If() when Guard_seq_N -> Expr_seq_N > end)(), > % or: > Worst = case true > of true when Guard_seq_1 -> Expr_seq_1 > ; true when Guard_seq_2 -> Expr_seq_2 > end. > ``` > What could be perceived as wrong with `if`? > > ~M > > -- > > But who will test the tests? > > > > > > From mjtruog@REDACTED Mon Aug 16 09:39:21 2021 From: mjtruog@REDACTED (Michael Truog) Date: Mon, 16 Aug 2021 00:39:21 -0700 Subject: Why do some people shun `if`? In-Reply-To: <20210814234458.7c1c9ceb@aesop> References: <20210814234458.7c1c9ceb@aesop> Message-ID: <106c305e-d3ef-5108-fe5d-0c0faea02975@gmail.com> If it is possible to use an "if" expression, it can result in better source code due to utilizing only guard expressions.? It is possible you may need to create an extra variable to use an "if" expression but that can help source code be more descriptive.? A "case" expression has more complex functionality by providing matching with guard expressions and it can result in more complex beam source code for the equivalent of an "if" expression (though it is likely that the compiler optimizations try to hide that when possible). Why prefer guard expressions only?? Guard expressions are the only pure expressions, i.e., no side-effects (if you assume node() is returning a constant) so they help to completely isolate state, making the source code easier to understand, use and test.? It is common for people to avoid "if" expressions because they don't feel comfortable with them, but it is best to use them as much as possible. On 8/14/21 2:44 PM, Michael P. wrote: > I once stumbled over someone's Erlang style guide, > they wanted no `if`. > It was not very well explained why, > and there was no obvious e-mail address, > or I wanted to first do > some thorough thinking about it. > Now I have no more than this: > > Is if not merely "syntactic sugar" for > a fun/0 with guarded clauses? > ``` > Now_this_is = (fun If() when Guard_seq_1 -> Expr_seq_1 > %% On and on and on > ; If() when Guard_seq_N -> Expr_seq_N > end)(), > % or: > Worst = case true > of true when Guard_seq_1 -> Expr_seq_1 > ; true when Guard_seq_2 -> Expr_seq_2 > end. > ``` > What could be perceived as wrong with `if`? > > ~M > > -- > > But who will test the tests? > > > > > > From vances@REDACTED Mon Aug 16 10:39:51 2021 From: vances@REDACTED (Vance Shipley) Date: Mon, 16 Aug 2021 16:39:51 +0800 Subject: Why do some people shun `if`? In-Reply-To: <106c305e-d3ef-5108-fe5d-0c0faea02975@gmail.com> References: <20210814234458.7c1c9ceb@aesop> <106c305e-d3ef-5108-fe5d-0c0faea02975@gmail.com> Message-ID: Why I find 'if' awkward is that when I test a condition for the success path and have a fall through clause for the fail path the semantics don't match with 'true'. if Foo == 42 -> ok; true -> {error, Foo} end. -- -Vance -------------- next part -------------- An HTML attachment was scrubbed... URL: From aperri@REDACTED Mon Aug 16 12:36:54 2021 From: aperri@REDACTED (Alberto Perri) Date: Mon, 16 Aug 2021 12:36:54 +0200 Subject: erflux on git hub Message-ID: Hello Erlang friends, i have been trying to run InfluxDB client for Erlang. You will find it at https://github.com/gossiperl/erflux. Could any of you explain to me how to run it. In the erflux_sup.erl file there is this line of code which states which module to pass to add_erflux/1 function -spec add_erflux( Name :: atom() ) -> statup_result(). %% @doc Starts instance of erflux with a given name. If name other than erflux_http, pid() versions of erflux_http functions have to be used. add_erflux(Name) -> add_erflux_internal( Name, #erflux_config{} ).a Alternatively the Read -- Alberto Perri aperri@REDACTED From aperri@REDACTED Mon Aug 16 13:13:09 2021 From: aperri@REDACTED (Alberto Perri) Date: Mon, 16 Aug 2021 13:13:09 +0200 Subject: erflux on git hub Message-ID: <9d55c4ec-3042-49fe-84cb-c147e03eec33@www.fastmail.com> Hello Erlang friends, i have been trying to run InfluxDB client for Erlang. You will find it at https://github.com/gossiperl/erflux. Could any of you explain to me how to run it. In the erflux_sup.erl file there is a line of code after the Dyalizer section which states which erflux_http module must to pass to add_erflux/1 function -spec add_erflux( Name :: atom() ) -> statup_result(). %% @doc Starts instance of erflux with a given name. If name other than erflux_http, pid() versions of erflux_http functions have to be used. add_erflux(Name) -> add_erflux_internal( Name, #erflux_config{} ).a Alternatively the README.md file states that it can be run using the following Erlang BIFS Starting with default settings: application:ensure_all_started(erflux), erflux_sup:add_erflux(erflux_http), erflux_http:get_databases(). in above BIF "application:ensure_all_started(erflux), " erflux is mentioned, but regardless of whether I use erflux_http or eflux i get the following error application:ensure_all_started(erflux), erflux_sup:add_erflux(erflux_http), erflux_http:get_databases(). ** exception error: undefined function erflux_sup:add_erflux/1 I have compiled the *.erl files using "rebar3 compile" and can see the beam files in the ebin directories from the various applications. Can someone please help Best regards, Alberto Perri aperri@REDACTED From jesper.louis.andersen@REDACTED Mon Aug 16 13:40:05 2021 From: jesper.louis.andersen@REDACTED (Jesper Louis Andersen) Date: Mon, 16 Aug 2021 13:40:05 +0200 Subject: erflux on git hub In-Reply-To: References: Message-ID: The function is available in the module, so I'm inclined to think it's something with the load path. Try loading the module from the shell and check that it is present (commands l/1 and m/1, but they only work from the shell). On Mon, Aug 16, 2021 at 12:40 PM Alberto Perri wrote: > Hello Erlang friends, > > i have been trying to run InfluxDB client for Erlang. You will find it at > https://github.com/gossiperl/erflux. Could any of you explain to me how > to run it. > > In the erflux_sup.erl file there is this line of code which states which > module to pass to add_erflux/1 function > -spec add_erflux( Name :: atom() ) -> statup_result(). > %% @doc Starts instance of erflux with a given name. If name other than > erflux_http, pid() versions of erflux_http functions have to be used. > add_erflux(Name) -> > add_erflux_internal( Name, #erflux_config{} ).a > > Alternatively the Read > > > > -- > Alberto Perri > aperri@REDACTED > -- J. -------------- next part -------------- An HTML attachment was scrubbed... URL: From aperri@REDACTED Mon Aug 16 18:37:21 2021 From: aperri@REDACTED (Alberto Perri) Date: Mon, 16 Aug 2021 18:37:21 +0200 Subject: erflux on git hub In-Reply-To: References: Message-ID: Dear Jesper, using rebar3 shell and then tying in the following lines as instructed by the creator of the code, Radoslaw aperri@REDACTED:~/try$ rebar3 shell ===> Verifying dependencies... Erlang/OTP 24 [erts-12.0.3] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [jit] Eshell V12.0.3 (abort with ^G) 1> application:load(erflux), 1> application:set_env(erflux, host, <<"localhost">>), 1> application:set_env(erflux, port, 8086), 1> application:set_env(erflux, username, <<"root">>), 1> application:set_env(erflux, password, <<"root">>), 1> application:set_env(erflux, ssl, false), 1> application:set_env(erflux, timeout, infinity), 1> application:ensure_all_started(erflux), 1> erflux_sup:add_erflux(erflux_http). {ok,<0.253.0>} was OK until this line which generates an http error for not being able to find a file. 2> erflux_http:get_databases(). {error,404} 3> in the code there are a series of defines all to do with a database. -define(DATABASE_NAME, erfluxtest). -define(DATABASE_ADMIN, testadmin). -define(DATABASE_USER, testuser). -define(DATABASE_USER_PASS, testpass). -define(SERIES_NAME, testseries). -define(DATABASE_NAME_ATOM, <<"erfluxtest">>). -define(DATABASE_ADMIN_ATOM, <<"testadmin">>). -define(DATABASE_USER_ATOM, <<"testuser">>). I have inFlux DB installed in Debian buster running locally. Would I have to create the database name, user and password, in InFlux DB that corresponds to the above defines before running the code? I really trying to get oriented on how to use Radoslaw application, Would you know what to do to help me out with this. Thanks, Alberto -- Alberto Perri aperri@REDACTED On Mon, Aug 16, 2021, at 1:40 PM, Jesper Louis Andersen wrote: > The function is available in the module, so I'm inclined to think it's something with the load path. Try loading the module from the shell and check that it is present (commands l/1 and m/1, but they only work from the shell). > > On Mon, Aug 16, 2021 at 12:40 PM Alberto Perri wrote: >> Hello Erlang friends, >> >> i have been trying to run InfluxDB client for Erlang. You will find it at https://github.com/gossiperl/erflux. Could any of you explain to me how to run it. >> >> In the erflux_sup.erl file there is this line of code which states which module to pass to add_erflux/1 function >> -spec add_erflux( Name :: atom() ) -> statup_result(). >> %% @doc Starts instance of erflux with a given name. If name other than erflux_http, pid() versions of erflux_http functions have to be used. >> add_erflux(Name) -> >> add_erflux_internal( Name, #erflux_config{} ).a >> >> Alternatively the Read >> >> >> >> -- >> Alberto Perri >> aperri@REDACTED > > > -- > J. -------------- next part -------------- An HTML attachment was scrubbed... URL: From empro2@REDACTED Tue Aug 17 12:03:50 2021 From: empro2@REDACTED (Michael P.) Date: Tue, 17 Aug 2021 12:03:50 +0200 Subject: Why do some people shun `if`? In-Reply-To: References: <20210814234458.7c1c9ceb@aesop> <106c305e-d3ef-5108-fe5d-0c0faea02975@gmail.com> Message-ID: <20210817120350.5b376f83@aesop> On Mon, 16 Aug 2021 16:39:51 +0800 Vance Shipley wrote: > Why I find 'if' awkward is that when I test a condition for the success > path and have a fall through clause for the fail path the semantics don't > match with 'true'. > > if > Foo == 42 -> > ok; > true -> > {error, Foo} > end. I cannot identify any "falling through": no 'C-switch-case-no-break', not in the "true" = 'C-switch-default' or 'else'. I think I remember having employed some `-define(if_not, true)` when negation-or-ing all previous conditions seemed too "dangerous". ~M -- But who will test the tests? From empro2@REDACTED Tue Aug 17 15:12:44 2021 From: empro2@REDACTED (Michael P.) Date: Tue, 17 Aug 2021 15:12:44 +0200 Subject: Why do some people shun `if`? In-Reply-To: <106c305e-d3ef-5108-fe5d-0c0faea02975@gmail.com> References: <20210814234458.7c1c9ceb@aesop> <106c305e-d3ef-5108-fe5d-0c0faea02975@gmail.com> Message-ID: <20210817151244.131fd446@aesop> On Mon, 16 Aug 2021 00:39:21 -0700 Michael Truog wrote: > If it is possible to use an "if" expression, > it can result in better > source code due to utilizing only guard expressions. Which could also be done as a module function, a `fun`, a `case`. And others argue that 'it can result in worse' too. > It is possible you > may need to create an extra variable to use an "if" expression but that > can help source code be more descriptive. I might always use `if` as a match-operator expression-operand (RHS of `=`); the name of the result telling what the decision is about. If that is what you mean. >? A "case" expression [...] can result in more complex beam source code I consider this premature optimisation. Did I not read, once upon a time, that both `if` and `case` were compiled to `fun` anyway ... > Why prefer guard expressions only? But `if` is not required for "guard expressions only"? ``` f(). A = 1. B = 2. Max = if A >= B -> A ; A < B -> B end. Best = case true of true when A >= B -> A ; true when A < B -> B end. What_if = (fun If() when A >= B -> A ; If() when A < B -> B end)(). Now_this_is = (fun () when A >= B -> A ; () when A < B -> B end)(). ``` (These are months ... years old syntax experiments: what if I dumped `if`? Later found out I had also re-invented Kiwi-format.) > "if" expressions [...] it is best to use them as much as possible. Not at the statement, not at all at you, merely about the collision with the thread read before: that made me laugh myself off the chair. And it made me remember how wrong I was: 20 years ago I assumed that all such questions had already been finally resolved in the 20 years before _then_. ~Michael -- The name "Michael" is, more or less, a Hebrew version of Arabic 'allahu akbar'. From empro2@REDACTED Tue Aug 17 16:29:53 2021 From: empro2@REDACTED (Michael P.) Date: Tue, 17 Aug 2021 16:29:53 +0200 Subject: Why do some people shun `if`? In-Reply-To: <20210814234458.7c1c9ceb@aesop> References: <20210814234458.7c1c9ceb@aesop> Message-ID: <20210817162953.4945f8f0@aesop> So far, I have been using `if` to tell other programmers (and myself) that the following decision a) is not of general use (=> module function); b) not repeated or required by some other function (=> fun); c) is made without patterns (=> case); d) depends only on pure functions. And because it is a bit more readable than `(fun () ...)()`. Every function is a decision table, from trivial to complex. The pattern-matcher in my brain made me perceive both `if` and `case` as mere subsets of `fun`. Especially some larger `case` looks just like a `fun`, except at the top and bottom. Yesterday, or so, I discovered that they also, both, lack the "(let ...)"-y nature of `fun`. (I could have realised that half a year ago, when Craig told me that patterns in `case` do not introduce a new scope. But my head was fully enganged in trying to see any sapiens in calling an annotation an operator.) Now, all my `if` and `case` code shifts into the surrounding scope. Could that be some cause of the apparent contradiction in this thread: 'try to avoid `if`' <=/=> 'try to use `if`'? Or is this caused by two, each good and well, but mutually exclusive "approaches"? I need to watch that "if = harmful" video again that Ben pointed to, and digest it. I need to try again to understand Jespers excellent explanation (I can see from tone and structure that it is, one cannot demand one-read-no-think explanations). And, no less, I need to reconsider all the other hints and then stitch it all together. ~M -- But who will test the tests? From empro2@REDACTED Tue Aug 17 16:41:37 2021 From: empro2@REDACTED (Michael P.) Date: Tue, 17 Aug 2021 16:41:37 +0200 Subject: Long string to short ID In-Reply-To: <823C0925-1D03-49AB-939D-1D614E2B2761@writersglen.com> References: <20210814183728.GD15870@savella.carfax.org.uk> <823C0925-1D03-49AB-939D-1D614E2B2761@writersglen.com> Message-ID: <20210817164137.3d60423d@aesop> On Sat, 14 Aug 2021 15:32:56 -0400 "Lloyd R. Prentice" wrote: > You and others have given me much to consider and I?m vastly grateful. I am still failing to see how others seem to have been able to understand your use-case. That makes me worry about what else I could fail to see. I fail in associating "human-readable" with UUIDs. I associate "reading" with 'acquiring information': so I would not call youtube VIDs readable, but spellable, legible (as long as not noted down by hand). To me "reading" base64 codes sounds like trying to compete with recitation of Vogon poetry. I am able to demote "readable" to "spellable" or "pronounceable", but that was thwarted by speak of deriving from the title, and by the premise of the subject 'text -> ID'. I hate to steal people's time, I am aware that this all is very #erlounge-y, but I need to finish this out of my mind: a) Why go beyond IDs like `32#1, 32#2, ...`? b) Is this about automated derivation of "alternative titles"? ~M P. S. I meant `list_to_existing_atom`, not "...known_atom". That's how fluent I am in Erlang ... :-( -- Curiosity killed the cat -- by simply using up its time. From empro2@REDACTED Tue Aug 17 17:05:43 2021 From: empro2@REDACTED (Michael P.) Date: Tue, 17 Aug 2021 17:05:43 +0200 Subject: Why, for example, maps but array? In-Reply-To: References: <135BD767-183A-4549-ADCC-D2AE1295E76E@niemier.pl> Message-ID: <20210817170543.606933ad@aesop> On Mon, 16 Aug 2021 13:38:02 +1200 "Richard O'Keefe" wrote: Much more elaborate than my "Who will save the attributes? in `mv file from ext4 -> FAT12 -> ext4?" > Honestly, the deeper I look into *any* operating system issue the > more I dread woodpeckers [%]. Honestly, deeper look into *any* system => more dread. "The oldest, largest, most buggy piece of legacy software in constant maintenace: human society." ~M -- ... From empro2@REDACTED Tue Aug 17 17:32:50 2021 From: empro2@REDACTED (Michael P.) Date: Tue, 17 Aug 2021 17:32:50 +0200 Subject: Why is there no `file:move` (was: Why, [...] maps but array?) In-Reply-To: References: <20210815002734.3f358965@aesop> Message-ID: <20210817173250.5640ff5f@aesop> On Sat, 14 Aug 2021 18:42:40 -0400 "Lloyd R. Prentice" wrote: I cannot assess the perils that may lurk within this: ``` move_file(From, To) -> Content = file:read_file(From), file:write_file(To, Content), file:delete(From). ``` Thus, such is not fit for inclusion in "the library". It may serve some purpose, but its flaws would lead to people desiring, requesting, and possibly demanding some `file:DWIM...`. And relieving such desire is not feasible: deeper look into system => more dread => more work. So each gets to write their own DWYW function or module, be content with it, maybe spread it, suffer from its flaws, develop it, discuss it. And, at some time, possibly, it may be included in "the library", making Erlang a better language. ~Michael -- Reasonable is that which cannot be criticised reasonably anymore. From develop7@REDACTED Wed Aug 18 09:01:34 2021 From: develop7@REDACTED (Andrei Dziahel) Date: Wed, 18 Aug 2021 09:01:34 +0200 Subject: Why is there no `file:move` (was: Why, [...] maps but array?) In-Reply-To: <20210817173250.5640ff5f@aesop> References: <20210815002734.3f358965@aesop> <20210817173250.5640ff5f@aesop> Message-ID: Try file:rename On Tue, Aug 17, 2021, 17:33 Michael P. wrote: > On Sat, 14 Aug 2021 18:42:40 -0400 > "Lloyd R. Prentice" wrote: > > I cannot assess the perils that may lurk within this: > ``` > move_file(From, To) -> > Content = file:read_file(From), > file:write_file(To, Content), > file:delete(From). > > ``` > Thus, such is not fit for inclusion in "the library". > > It may serve some purpose, but its flaws > would lead to people desiring, requesting, > and possibly demanding some `file:DWIM...`. > And relieving such desire is not feasible: > deeper look into system => more dread => more work. > > So each gets to write their own DWYW function or module, > be content with it, maybe spread it, > suffer from its flaws, develop it, discuss it. > And, at some time, possibly, it may be included in "the library", > making Erlang a better language. > > ~Michael > > -- > > Reasonable is that which cannot be > criticised reasonably anymore. > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hugo@REDACTED Wed Aug 18 09:12:10 2021 From: hugo@REDACTED (Hugo Mills) Date: Wed, 18 Aug 2021 08:12:10 +0100 Subject: Why is there no `file:move` (was: Why, [...] maps but array?) In-Reply-To: References: <20210815002734.3f358965@aesop> <20210817173250.5640ff5f@aesop> Message-ID: <20210818071210.GA12086@savella.carfax.org.uk> On POSIX systems at least, that's got very limited capabilities -- you can't rename a file across a mount boundary. Things like mv start with that, but then have to fall back to making reflink copies(*) and then simple byte-by-byte copy if the reflink fails. If it can't use rename, it has to deal with copying all of the metadata as well as all the file contents, as it's creating a new file before deleting the old one. Python has os.rename, which implements only the rename(2) syscall, but then expands on that with the much more involved shutil module, which has copy and copy2 functions, which do all the complicated fallbacks and metadata duplication (to different levels of precision). Hugo. (*) Server-side copy, for some networked filesystems; CoW filesystems have something that behaves similarly. btrfs calls it a reflink copy. On Wed, Aug 18, 2021 at 09:01:34AM +0200, Andrei Dziahel wrote: > Try file:rename > > On Tue, Aug 17, 2021, 17:33 Michael P. wrote: > > > On Sat, 14 Aug 2021 18:42:40 -0400 > > "Lloyd R. Prentice" wrote: > > > > I cannot assess the perils that may lurk within this: > > ``` > > move_file(From, To) -> > > Content = file:read_file(From), > > file:write_file(To, Content), > > file:delete(From). > > > > ``` > > Thus, such is not fit for inclusion in "the library". > > > > It may serve some purpose, but its flaws > > would lead to people desiring, requesting, > > and possibly demanding some `file:DWIM...`. > > And relieving such desire is not feasible: > > deeper look into system => more dread => more work. > > > > So each gets to write their own DWYW function or module, > > be content with it, maybe spread it, > > suffer from its flaws, develop it, discuss it. > > And, at some time, possibly, it may be included in "the library", > > making Erlang a better language. > > > > ~Michael > > -- Hugo Mills | The gates of heaven will always be closed to the hugo@REDACTED carfax.org.uk | Morris dancers. http://carfax.org.uk/ | PGP: E2AB1DE4 | William Prynne From empro2@REDACTED Wed Aug 18 12:36:20 2021 From: empro2@REDACTED (Michael P.) Date: Wed, 18 Aug 2021 12:36:20 +0200 Subject: Fundamental differences around patterns Message-ID: <20210818123620.3f9590a5@aesop> Boundies and unboundies in patterns are "fundamentally different" (Raimo's wording). "And explicit is better than implicit." (Zen of Python) I might have identified three more fundamental differences. (The first one might have been done with too quickly.) I will use `val` as a pattern boundie annotation; `val` says what it means and is somehow related to `var`, which is, kind of, implied for unboundies by the pattern context. And it does not conjure up detrimental associations in Elixir programmers. ------------- At least someone said they would often repeat a variable within patterns, so let B have no binding and us be explicit and consistent: % scope 1 {B, val B} = Expr % scope 2 (within match operation) There is a fundamental difference between the first and the second occurrence of B. It exists only within the match operation. But annotation could warn of redundancy (naming of term instead of that term's function). Annotate? ------------- A will already be bound by case "sneak-export" and will be evaluated to be matched with the `case` result; and it might not be what was intended; so, to be explicit and consistent: val A = case 1 of A -> A end. Annotate? ------------- Being a "sneak-export" makes `U` fundamentally different from the other unboundies: %% Let A, B, U be unbound. case Expr of {var U, A} when A ... -> Expr_seq_1; {var U, B} -> Expr_seq_2 end, Explicit is better than implicit, so: annotate? Alternatives: var, let, sneak, push, shove, ... (Related to, but possibly better kept apart from 'val' ...) ------------- I fail to assess how fundamental all this is: P = ..., V = ..., F = fun F(V) -> N = ..., F({V, N, super V, super P}) end Let alone `super F` ... OC, there are alternatives: super, prev, ext, imp, grab, close, ^ The last one is git-y, but is bound to conjure up detrimental associations in Elixir programmers. Related too, but possibly better kept apart from 'val' ... ------------- Explicit is better than implicit, but is the binding implied by pattern context explicit or implicit or between-we-sit? I am not sure that there is much problem to be solved, much trouble being prevented by the nature of Erlang. OC, for the 733t wizard there is no problem at all, but the nature of Erlang might be altered to prevent even more trouble ... ~M -- "So, here we go again Searching for the truth Until the twelfth of never" From empro2@REDACTED Wed Aug 18 14:04:10 2021 From: empro2@REDACTED (Michael P.) Date: Wed, 18 Aug 2021 14:04:10 +0200 Subject: What use is `case` sneak- binding? Message-ID: <20210818140410.697a49ff@aesop> What use is the sneaky "slot-machine" nature of how `case` treats pattern unboundies Does it simplify the implementation of `case`? OC, `case` has to _try_ to match the patterns and cannot simply dump every new binding. Unbinding on badmatch or repeating the matching or transferring new bindings after success in some subscope might complicate the implementation. And sounds a bit like backtracking, and Erlang was designed with a 'no backtracking' premise ... yet there cannot be any side-effects as the only expression allowed in patterns is 'variables', the `case` switch is evaluated only once anyway ... and now I have shipped off the brink of my tiny world. Giving `case` the '(let)' after 35 years hits "the legacy wall". What would one lose when the "slot-machine" scared one into some Switch = ..., Result = (fun Case(...) when ... -> ...; Case(...) when ... -> ... end)(Switch), ? ~M -- Normality is merely a question of quantity, not of quality. Normalit?t ist nur eine Frage von Quantit?t, nicht von Qualit?t. From karolis.velicka@REDACTED Wed Aug 18 14:17:44 2021 From: karolis.velicka@REDACTED (Karl Velicka) Date: Wed, 18 Aug 2021 13:17:44 +0100 Subject: What use is `case` sneak- binding? In-Reply-To: <20210818140410.697a49ff@aesop> References: <20210818140410.697a49ff@aesop> Message-ID: Hi Michael, Apologies if I'm just missing something obvious or I'm missing some key context, but to me your message/question contains a lot of unfamiliar terminology and hyperbole which makes it hard to understand what you're getting at. What is "sneak-binding"? Sneaky "slot machine" nature? It would be really helpful if you could give a more concrete example of what you dislike about case (the less ellipsis the better!), and a similar piece of code rewritten following your suggestion (I _think_ you're making a suggestion without message, but I'm not actually entirely sure..) Thanks, Karl On Wed, 18 Aug 2021 at 13:04, Michael P. wrote: > What use is the sneaky "slot-machine" nature of > how `case` treats pattern unboundies > > Does it simplify the implementation of `case`? > > OC, `case` has to _try_ to match the patterns and cannot > simply dump every new binding. Unbinding on badmatch or > repeating the matching or transferring new bindings > after success in some subscope might complicate > the implementation. And sounds a bit like backtracking, > and Erlang was designed with a 'no backtracking' premise ... > yet there cannot be any side-effects as the only expression > allowed in patterns is 'variables', the `case` switch > is evaluated only once anyway ... and now I have shipped > off the brink of my tiny world. > > Giving `case` the '(let)' after 35 years hits "the legacy wall". > > What would one lose when the "slot-machine" scared > one into some > > Switch = ..., > Result = (fun Case(...) when ... -> ...; > Case(...) when ... -> ... > end)(Switch), > ? > > ~M > > -- > > Normality is merely a question of quantity, > not of quality. > > Normalit?t ist nur eine Frage von Quantit?t, > nicht von Qualit?t. > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From raoknz@REDACTED Wed Aug 18 14:49:44 2021 From: raoknz@REDACTED (Richard O'Keefe) Date: Thu, 19 Aug 2021 00:49:44 +1200 Subject: Long string to short ID In-Reply-To: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> References: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> Message-ID: If you mean "a ID", the answer is that it cannot be done, because book titles are not unique. For example, there is a book called "Inferno" by Dan Brown, and there is another book called "Inferno" by Larry Niven and Jerry Pournelle. (The latter is thought-provoking; the former is Dan Brown being Dan Brown.) Discussions of what a book title even _is_ require the skills of a William Kent of "Data and Reality" fame. Is a subtitle included? Is the edition part of the title? Are translations that preserve the title the same book or different books? Should "Football Girl" and "The Football Girl" count as the same title? What do you do with numeric titles like "1632" or ones with non-linear aspects, like Great Misteaks with a slash through the "e" in "Misteaks", a caret under and between the "ks", and an "e" above and between the "ks"? (It turns out that I was thinking of "Incompetence" by Rob Grant, Incompetence : Rob Grant : 9780575074491 (bookdepository.com) .) Then there are variations in spelling:"The Discovery of Witchcraft" (modern spelling) vs "The Discoverie of Witchcraft" (original spelling), with a semantic change thrown in for good measure (it's really the Uncovering of Witchcraft). Did I mention my grandfather from near Tucepi? If you have two books with identical contents except that one uses the Cyrillic script and the other uses the Latin script, do they have the same title or different titles? Should they get the same ID? To a first approximation, I suppose we could say that anything that is listed as a book title in "Books in Print" is a book title, and there are apparently some 12 million titles currently in print in English. (Sigh. I am never going to read them all. I am never even going to read all the ones I would *enjoy* reading.) Then we have to clarify what "human-readable" means. Are ISBN-13s "human-readable"? Do you want a human who reads the ID to have any clue about the title or contents of the book? As it happens, I have spent a LOT of time recently filing electronic copies of reports &c that I've collected over the decades. The best answer I have found? USE THE TITLE VERBATIM Anything else WILL lose information. In fact I've had to ADD author information in some cases. "Inferno@REDACTED: "Inferno@REDACTED" for example (if I had those books on my disc). Come to think of it, "Data and Reality" is a really good book. William Kent thought he was writing about data bases. When I read it, I thought he was talking about (symbolic) Artificial Intelligene. Names (titles) are for people, and are not unique. Surrogates (IDs) are for computers, and are not self-explanatory. I think we need to know a heck of a lot more about your use case. On Sat, 14 Aug 2021 at 07:44, Lloyd R. Prentice wrote: > > Hello, > > What might be a nifty way to turn a long book title with spaces into a short human-readable ID? > > Thanks, > > LRP > > Sent from my iPad From mjtruog@REDACTED Wed Aug 18 19:22:47 2021 From: mjtruog@REDACTED (Michael Truog) Date: Wed, 18 Aug 2021 10:22:47 -0700 Subject: Long string to short ID In-Reply-To: References: <8B1E27CE-8524-482B-AB7B-8E9B20B792ED@writersglen.com> Message-ID: <96d03553-64e9-1fdf-2329-e8f02ae66d8a@gmail.com> The main limiting factor is likely the filesystem and modern filesystems are typically limiting you to 255 characters.? A title shouldn't have problems with that limitation. I try to have a year prefix on files to keep track of when they are created (often with month and day as YYYYMMDD) to ensure the information isn't lost if the file gets copied.? Having the creation time as a prefix can make the file easier to find because you often know roughly what it should be when you are attempting to find the file.? A year prefix would be a way of distinguishing different editions of the same title with the same author. On 8/18/21 5:49 AM, Richard O'Keefe wrote: > If you mean "a ID", the answer is that it cannot be done, > because book titles are not unique. > For example, there is a book called "Inferno" by Dan Brown, > and there is another book called "Inferno" by Larry Niven and Jerry Pournelle. > (The latter is thought-provoking; the former is Dan Brown being Dan Brown.) > > Discussions of what a book title even _is_ require the skills of a > William Kent of "Data and Reality" fame. > Is a subtitle included? Is the edition part of the title? Are > translations that preserve the title the same > book or different books? Should "Football Girl" and "The Football > Girl" count as the same title? > What do you do with numeric titles like "1632" or ones with non-linear > aspects, like > Great Misteaks with a slash through the "e" in "Misteaks", a caret > under and between the "ks", > and an "e" above and between the "ks"? (It turns out that I was > thinking of "Incompetence" by > Rob Grant, Incompetence : Rob Grant : 9780575074491 (bookdepository.com) .) > Then there are variations in spelling:"The Discovery of Witchcraft" > (modern spelling) vs > "The Discoverie of Witchcraft" (original spelling), with a semantic > change thrown in for good > measure (it's really the Uncovering of Witchcraft). Did I mention my > grandfather from near > Tucepi? If you have two books with identical contents except that one > uses the Cyrillic script and > the other uses the Latin script, do they have the same title or > different titles? Should they get the > same ID? > > To a first approximation, I suppose we could say that anything that is > listed as a book title in > "Books in Print" is a book title, and there are apparently some 12 > million titles currently in print > in English. (Sigh. I am never going to read them all. I am never > even going to read all the ones > I would *enjoy* reading.) > > Then we have to clarify what "human-readable" means. > Are ISBN-13s "human-readable"? > Do you want a human who reads the ID to have any clue about the title > or contents of the book? > > As it happens, I have spent a LOT of time recently filing electronic > copies of reports &c that I've > collected over the decades. The best answer I have found? > > USE THE TITLE VERBATIM > > Anything else WILL lose information. In fact I've had to ADD author > information in some cases. > "Inferno@REDACTED: "Inferno@REDACTED" for example (if I had those > books on my disc). > > Come to think of it, "Data and Reality" is a really good book. > William Kent thought he was writing > about data bases. When I read it, I thought he was talking about > (symbolic) Artificial Intelligene. > Names (titles) are for people, and are not unique. > Surrogates (IDs) are for computers, and are not self-explanatory. > > I think we need to know a heck of a lot more about your use case. > > On Sat, 14 Aug 2021 at 07:44, Lloyd R. Prentice wrote: >> Hello, >> >> What might be a nifty way to turn a long book title with spaces into a short human-readable ID? >> >> Thanks, >> >> LRP >> >> Sent from my iPad From empro2@REDACTED Wed Aug 18 21:10:37 2021 From: empro2@REDACTED (Michael P.) Date: Wed, 18 Aug 2021 21:10:37 +0200 Subject: Why do some people shun `if`? In-Reply-To: <20210814234458.7c1c9ceb@aesop> References: <20210814234458.7c1c9ceb@aesop> Message-ID: <20210818211037.6efa584d@aesop> > On Sun, Aug 15, 2021 at 6:48 AM zxq9 wrote: > > You can still always do the same thing with a `case` using guards, > > though -- and as you mentioned you *could* do the same with funs, but > > that's a bit crazy as you're invoking the lambda machinery Have just stumbled across this (looking for s/th else, but remembered): "The difference between function calls and `case ... of` are very minimal: in fact, they are represented the same way at a lower level, and using one or the other effectively has the same cost in terms of performance." -- https://learnyousomeerlang.com/syntax-in-functions#in-case-of [Reply is a bit constructed, original msg deleted, no msg id from the archive and no clue how to put it in even if] ~M -- ??|-_|-_|-_-|????????????(o_o)_o)_o)_o)_o)_o)_o)_o)_o)_o)_o)_o)_o)_o) "We're concerned / You're a threat / You're not integral to the project" From empro2@REDACTED Wed Aug 18 22:51:00 2021 From: empro2@REDACTED (Michael P.) Date: Wed, 18 Aug 2021 22:51:00 +0200 Subject: What use are `case` bindings? (was: What use [...] sneak[...]) In-Reply-To: References: <20210818140410.697a49ff@aesop> Message-ID: <20210818225100.1ae8d956@aesop> On Wed, 18 Aug 2021 13:17:44 +0100 Karl Velicka wrote: > Thanks, Thank _you_! I have evidently but not obviously edited it to death. I tried to be concise, but the info in the text deleted was still in my mind and ... death edit. Hope I didn't delete too quickly ... 8-( All the fine explanations ... "lost in time, like -- tears in the rain." --------------- Being '(let)-y' is to mean that it all has its own scope, like a `fun` has, from its recursion name, through the pattern list of each clause, and any guard sequences, to the expression sequence in each clause. Making `case` behave '(let)-y' would prevent it from creating any bindings that exist beyond its `end` or could not-match with a binding from before `case`. The "legacy wall" means 'Cannot be changed, because everyone has used it everywhere.' F...ine! There is no "slot-machine" ... Did `case` once behave like this? put a variable getting bound in a pattern outside the `case` only if the variable occurred in the pattern of each clause? I cannot find mention of such now. The notes were a bit old; trying to follow some netiquette I try to have a thought of my own before stealing other people's time with postings. ---------------- The only thing remaining a bit "sneaky", is that I cannot find now any mention of the bindings `case` can create; bindings that live on beyond `end` and can collide with non-matching bindings from before `case`. So the question can be altered into: What use are `case` bindings? "Strictly speaking, `case` is unnecessary. This is how filter would have been defined using pure pattern matching: [module functions]" -- Sec. 4.8, p. 68, _Programming_Erlang_Second_Edition_, by Joe Armstrong, edited by S. D. Pfalzer What is unpure about `case` pattern matching? When `case` is explained, there is little binding at all. And with it looking like a function and "The return value of Body is the return value of the case expression." -- https://erlang.org/doc/reference_manual/expressions.html people, like me, might think it was as '(let)-y' as a `fun` -- and use it that way, raising the last of the orginal questions: What would one lose when "unpure" `case` scared one into some Switch = ..., Result = (fun Case(...) when ... -> ...; Case(...) when ... -> ... end)(Switch), ? ~M -- The clever man acquires the knowledge of other clever men; the sage can also learn from the fool. From empro2@REDACTED Thu Aug 19 00:25:43 2021 From: empro2@REDACTED (Michael P.) Date: Thu, 19 Aug 2021 00:25:43 +0200 Subject: Fundamental differences around patterns In-Reply-To: <20210818123620.3f9590a5@aesop> References: <20210818123620.3f9590a5@aesop> Message-ID: <20210819002543.1bf58a82@aesop> On Wed, 18 Aug 2021 12:36:20 +0200 "Michael P." wrote: ---8<---8<---8< > ------------- > [...] > %% Let A, B, U be unbound. > [...] > Alternatives: var, let, sneak, push, shove, ... > [...} > ------------- ---8<---8<---8< Please, ignore this section. It is non-sense based on an old misunderstanding. ~M -- The oldest, largest, most buggy piece of legacy software in constant maintenace: human society. From empro2@REDACTED Thu Aug 19 00:51:20 2021 From: empro2@REDACTED (Michael P.) Date: Thu, 19 Aug 2021 00:51:20 +0200 Subject: Why, for example, maps but array? In-Reply-To: References: <20210815002734.3f358965@aesop> Message-ID: <20210819005120.5a8e2fba@aesop> On Sun, 15 Aug 2021 13:57:42 +0900 zxq9 wrote: > There is something to this... > [...] > >> The decision seems to depend on author > >> and some tossing of coins. > > ...and this as well. Yes, and yet it is not helpful. Not as painfully embarrassing as some of my lines, but if I could turn back time ... I know you mean well, but, alas! your not ignoring such is also not helpful. (*nodding of heads*) I do not need encouragement, (*straining of necks due to strong nodding*) I need information. And I am really trying to ask for it. And only after a lot of research. Let us all try to stay focussed, and restrain ourselves a bit. :-) ~M -- CAR and CiDeR give me a pleasant mediterranean feeling, whereas CuDdeR makes me shudder. From raoknz@REDACTED Thu Aug 19 08:43:22 2021 From: raoknz@REDACTED (Richard O'Keefe) Date: Thu, 19 Aug 2021 18:43:22 +1200 Subject: What use is `case` sneak- binding? In-Reply-To: References: <20210818140410.697a49ff@aesop> Message-ID: What Karl Velicka said. With knobs on. I honestly haven't the least idea what the question is. Perhaps the whole point is that pattern matching and guard testing in "case" ISN"T in any way different from pattern matching and guard testing in functions, "fun", or "receive". It may be useful to recall that there was a time when Erlang did not have "fun" or list comprehensions, and the rule was utterly simple: the scope of a variable was the whole clause it appeared in, with NO nested scopes. This was inherited from Erlang's parents Prolog and Strand-88. I actually had a half-written paper completely destroyed by the addition of "fun" in Erlang, The rule I would have liked to see for "fun" and list comprehensions is that the *scope* of a variable would have continued to be the whole clause, but just as if ... -> X = 1 ; ... -> Y = 2 end might not bind X or Y, making X and Y still *visible* outside the "if" as the same variables but UNAVAILABLE because they might not be bound, so fun (X) -> Y = X end .... Y should have meant that one variable Y was involved, it just couldn't be USED at the last position because it might not be bound. But nobody asked me. This may or may not have anything to dow ith your question. I can't tell. On Thu, 19 Aug 2021 at 00:18, Karl Velicka wrote: > > Hi Michael, > > Apologies if I'm just missing something obvious or I'm missing some key context, but to me your message/question contains a lot of unfamiliar terminology and hyperbole which makes it hard to understand what you're getting at. > > What is "sneak-binding"? Sneaky "slot machine" nature? > > It would be really helpful if you could give a more concrete example of what you dislike about case (the less ellipsis the better!), and a similar piece of code rewritten following your suggestion (I _think_ you're making a suggestion without message, but I'm not actually entirely sure..) > > Thanks, > Karl > > On Wed, 18 Aug 2021 at 13:04, Michael P. wrote: >> >> What use is the sneaky "slot-machine" nature of >> how `case` treats pattern unboundies >> >> Does it simplify the implementation of `case`? >> >> OC, `case` has to _try_ to match the patterns and cannot >> simply dump every new binding. Unbinding on badmatch or >> repeating the matching or transferring new bindings >> after success in some subscope might complicate >> the implementation. And sounds a bit like backtracking, >> and Erlang was designed with a 'no backtracking' premise ... >> yet there cannot be any side-effects as the only expression >> allowed in patterns is 'variables', the `case` switch >> is evaluated only once anyway ... and now I have shipped >> off the brink of my tiny world. >> >> Giving `case` the '(let)' after 35 years hits "the legacy wall". >> >> What would one lose when the "slot-machine" scared >> one into some >> >> Switch = ..., >> Result = (fun Case(...) when ... -> ...; >> Case(...) when ... -> ... >> end)(Switch), >> ? >> >> ~M >> >> -- >> >> Normality is merely a question of quantity, >> not of quality. >> >> Normalit?t ist nur eine Frage von Quantit?t, >> nicht von Qualit?t. >> >> >> From jeroen@REDACTED Fri Aug 20 09:52:02 2021 From: jeroen@REDACTED (Jeroen Koops) Date: Fri, 20 Aug 2021 09:52:02 +0200 Subject: Lacuna Space looking for Erlang developer Message-ID: Lacuna Space, a UK and Netherlands based startup offering IoT connectivity using its own fleet of small satellites, is looking for an experienced Erlang developer to join the team. Responsibilities: * Design, code and test new features for Lacuna's backend system in Erlang/OTP * Find and solve defects in the systems currently in use * Liaise with the payload firmware team to realise features to be implemented across both the payload and the backend Skills and Experience: * Demonstrable experience (3+ years) developing systems in Erlang/OTP * Able to manage themselve, and to make themselve valuable in a fast-moving company * Knowledge of SQL databases * Experience with Linux * Good verbal and written communication in English * Desirable: - experience in any of the following: C, Docker, PostgreSQL, Python - experience with, or an interest in spaceflight and orbital mechanics - experience with, or an interest in Lora, LoraWan and IoT Other: * This is a remote position, you will be working from home most of the time * Both contractors or employees will be considered * At this point, only candidates from the United Kingdom will be considered. This is non-negotiable - we have run this posting before, and although a significant number of qualified candidates replied, we had to turn most of them down immediately because they were not UK residents. To apply, please send resume and cover letter to Jeroen Koops About Lacuna Space Lacuna Space, based in the UK and the Netherlands, is a global Internet of Things (IoT) connectivity provider. It offers low cost, easy and reliable global connections to sensors and mobile equipment everywhere. The company is revolutionising the connection of sensors and equipment to the internet with low-power, wide-area networking technology. This connection revolution is being built around open-standards and freely available network chips that developers can easily configure into flexible and secure networks, ready to be deployed publicly, privately or by communities. Lacuna Space's plan is to deploy a constellation of small satellites in low Earth orbit (LEO) forming the Lacuna Network. Because the satellites travel in polar orbits, the Lacuna Network will provide ubiquitous coverage for devices in regions without reliable wireless coverage. The company works closely with The Things Network in Amsterdam. Its network includes developers and collaborators in the US, France and Switzerland. -- Jeroen Koops | jeroen@REDACTED | www.lacuna.space | +31-(6)-55590300 -------------- next part -------------- An HTML attachment was scrubbed... URL: From serge@REDACTED Sat Aug 21 02:59:35 2021 From: serge@REDACTED (Serge Aleynikov) Date: Fri, 20 Aug 2021 20:59:35 -0400 Subject: [ANN] etran: added map-reduce comprehension Message-ID: Dear Erlangers, I just pushed the release 0.2 of the etrans application that adds a parse transform for extending the standard list comprehensions with the ability to fold a list, given the initial state. https://github.com/saleyn/etran This is similar to the lists:foldl/2 and lists:mapfoldl/2 functions: Given: L = [1,2,3] 1. Fold Comprehension: 6 = [S+I || S = 0, I <- L]. %% Translates to: lists:foldl(fun(I,S) -> S+I end, 0, L) 2. MapFold Comprehension: {[1,2,3], 6} = [{I, S+I} || S = 0, I <- L]. %% Translates to: lists:mapfoldl(fun(I,S) -> {I, S+I} end, 0, L) As an avid user of list comprehensions, I always missed the ability to do the fold on a list using a short-hand pattern syntax. This etran library lifts that restriction, potentially making the code more terse. Enjoy, Serge -------------- next part -------------- An HTML attachment was scrubbed... URL: From chargreezy@REDACTED Fri Aug 20 18:54:08 2021 From: chargreezy@REDACTED (Charlie Morgan) Date: Fri, 20 Aug 2021 09:54:08 -0700 Subject: ssl_client_session_cache size Message-ID: Hi! We have a lot of outgoing ssl connections and noticed that ssl_manager does not respect the default session_cache_client_max value and the ets session cache table increases unbounded until we hit the session lifetime. I have tried to write some tests to replicate this behavior but it's proving difficult, do you know of any circumstances that could be causing this? My initial thoughts were problems with ssl_manager:do_register_session. Currently using OTP24 Thanks! -------------- next part -------------- An HTML attachment was scrubbed... URL: From empro2@REDACTED Sat Aug 21 20:23:05 2021 From: empro2@REDACTED (Michael P.) Date: Sat, 21 Aug 2021 20:23:05 +0200 Subject: Why, for example, maps but array? In-Reply-To: References: <20210815002734.3f358965@aesop> Message-ID: <20210821202305.751d2ff9@aesop> On Sun, 15 Aug 2021 13:57:42 +0900 zxq9 wrote: > One layer is the semantic choice of "does the name of this module > indicate that this modules 'deals with Xs' or does it represent *a* > single X when the user is typing it?" Or neither: Implementation layer: I am working on 'the module that deals with Xs', or on 'the map module'? OO? 'represents one'? class CollectionOfXs but not CollectionsOfXs, or Xcollection On the application level, in, say: ... = lists:filter(...) ... = maps:filter(...) the name only makes the function name more specific by evoking some mind context (and for the compiler too). * division -> integer division (for all of them) * tree -> apple tree (no matter whether with 0, 1, 2, ... apples) > I like it when the naming semantic for the interface module to an X is > singular. It makes sense to me as a user of that module to say > `map:find(Key, Map)` rather than `maps:find(Key, Map)`, but also makes And others do like the opposite and cannot see any sense. The question is: why? > sense to have a separate module called actually `maps` for things like > the "List of Maps" module that I wrote a while back that was recently And `list_of_maps` is not `lists_of_maps`, and: * tree dealing with the production of apples -> appletree; * lom/map_list -> lom/motor_bike?! * PLIST, ALIST, proplist, List of maps -> maplist. OC, proplist is jest: it would pretend to somehow restrict associations or pairs to be properties. > probably under a different name). https://gitlab.com/zxq9/lom Good choice! (prejudice after two clicks) The pain of creating a ?soft github account is still fresh. The PR-speak, the bloat, that yucky Di$ney-ic imp made me wish that it had not been the web page I was looking for. Is collaboration between micro$soft github and gitlab practicable? (... and will it remain so? ...) > These semantic sort of things are quirks and no guideline for > formalizing them has been fleshed out. do_pseudo look > see > choose if test emergency -or urgency then toss coin done > Argument order regularity is also a bit of a crap shoot > throughout the stdlib, but over time you sort of learn it and stop caring. Yes, everyone can learn that, and this: there /= their /= they're, and your /= you're, and than /= then, and and the rest of English orthography, and the fun of German noun classes (genders), and German inflexions, and then: they cannot, or only brokenly, and with _constant_ effort, even if no longer aware of it because of practice. And they have to! but only because everyone always tells them that everyone can learn that ... > Fixing this stuff up would be cool, but takes a huge amount of effort There will be no consistency. It is enough to improve decisions taken now: * there will be more modules than there are now; * there will be more programmers than there are now. ????? ~Michael -- ? hexadecimal | decimal | octal | dual | binary Which one sticks out like a man in a Robin Hood costume, standing in the middle of a pond with a wooden duck on his head? From ingela.andin@REDACTED Mon Aug 23 11:45:13 2021 From: ingela.andin@REDACTED (Ingela Andin) Date: Mon, 23 Aug 2021 11:45:13 +0200 Subject: ssl_client_session_cache size In-Reply-To: References: Message-ID: Hi! Could you be a little more specific about the OTP-24 version. Is it 24.0 or a patch version? Also it would be appropriate to create a github issue instead of reporting it here, where you also provide a small recreation example. As far as I know this has been an issue in the past but should work for OTP-24. Our tests are passing, so we really need something more to go on. Regards Ingela Erlang/OTP team - Ericsson AB Den l?r 21 aug. 2021 kl 10:38 skrev Charlie Morgan : > Hi! > > We have a lot of outgoing ssl connections and noticed that ssl_manager > does not respect the default session_cache_client_max value and the ets > session cache table increases unbounded until we hit the session lifetime. > > I have tried to write some tests to replicate this behavior but it's > proving difficult, do you know of any circumstances that could be causing > this? My initial thoughts were problems with > ssl_manager:do_register_session. > > Currently using OTP24 > > Thanks! > -------------- next part -------------- An HTML attachment was scrubbed... URL: From chargreezy@REDACTED Mon Aug 23 18:07:38 2021 From: chargreezy@REDACTED (Charlie Morgan) Date: Mon, 23 Aug 2021 09:07:38 -0700 Subject: ssl_client_session_cache size In-Reply-To: References: Message-ID: Hey Ingela, Thanks for the reply, it's OTP 24.0.5. Understood, I was hesitant to make an issue as I was struggling to recreate although seeing it in deployment. I looked through the tests and I don't think this section actually has test coverage, in the meantime we have reduced the session cache lifetime to keep our memory down. Thanks, Charlie On Mon, Aug 23, 2021 at 2:45 AM Ingela Andin wrote: > Hi! > > Could you be a little more specific about the OTP-24 version. Is it 24.0 > or a patch version? Also it would be appropriate to create a github issue > instead of reporting it here, where you also provide a small recreation > example. As far as I know this has been an issue in the past but > should work for OTP-24. Our tests are passing, so we really need something > more to go on. > > Regards Ingela Erlang/OTP team - Ericsson AB > > Den l?r 21 aug. 2021 kl 10:38 skrev Charlie Morgan : > >> Hi! >> >> We have a lot of outgoing ssl connections and noticed that ssl_manager >> does not respect the default session_cache_client_max value and the ets >> session cache table increases unbounded until we hit the session lifetime. >> >> I have tried to write some tests to replicate this behavior but it's >> proving difficult, do you know of any circumstances that could be causing >> this? My initial thoughts were problems with >> ssl_manager:do_register_session. >> >> Currently using OTP24 >> >> Thanks! >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From brhemes@REDACTED Tue Aug 24 00:00:33 2021 From: brhemes@REDACTED (Brett Hemes) Date: Mon, 23 Aug 2021 22:00:33 +0000 Subject: I am close to using a behaviour as a pure interface and I feel dirty... Message-ID: ... should I? I have some servers that carry around references to other (let's call them child) servers. Each of the referenced child servers are doing their own thing and are implemented as different modules but also share some common functions (albeit with different implementations). At some point, I end up fetching a reference to a child server and want to make a call that is common to all of the child servers. As of right now I do not know what specific type (module) the child server is, only that they ALL offer some subset of functionality. Assuming I am not approaching this entirely wrong (which could be the case) I have identified two leading options for my case: 1) use a behaviour (perhaps improperly) as a pure interface (i.e., with only callbacks and no "general" functionality). For a child implemented in a `my_child_mod` module that implements behaviour `my_iface`, this could result in calls like `my_iface:a_common_fun(ChildServerRef)` after fetching the child server reference where I use the behaviour's module to access the child's functionality... OR 2) store the particular module of each child with the reference and use the stored module name at time of the call (and know/assume that all children have some shared functionality). So using some tuple or similar `{my_child_mod, ChildServerRef}` (versus just the reference) could result in a call like `my_child_mod:a_common_fun(ChildServerRef)` after fetching the reference info (as a tuple). I, perhaps naively, gravitate towards #1 above for various reasons (compile-time checks, only having to carry around refs, my C++ background, etc.), but the internet (and ferd in particular here (https://stackoverflow.com/questions/4119477/implementing-interfaces-in-erlang/4119615#4119615)) seems to imply that this is not the Erlang way (despite finding OTP cases like this: https://github.com/erlang/otp/blob/master/lib/ssh/src/ssh_sftpd_file_api.erl). ... shame on me? I am trying very hard to leave my C++ past behind and do things in the Erlang way, but need a little help in this particular case... Thanks, Brett -------------- next part -------------- An HTML attachment was scrubbed... URL: From s.ledenev@REDACTED Tue Aug 24 06:28:40 2021 From: s.ledenev@REDACTED (Stanislav Ledenev) Date: Tue, 24 Aug 2021 07:28:40 +0300 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: Erlang's behaviour is NOT an interface! If you are looking for some analogy from other languages the closest one is abstract classes in C#. ??, 24 ???. 2021 ?. ? 01:00, Brett Hemes : > ... should I? > > > > I have some servers that carry around references to other (let?s call them > child) servers. Each of the referenced child servers are doing their own > thing and are implemented as different modules but also share some common > functions (albeit with different implementations). At some point, I end up > fetching a reference to a child server and want to make a call that is > common to all of the child servers. As of right now I do not know what > specific type (module) the child server is, only that they ALL offer some > subset of functionality. > > > > Assuming I am not approaching this entirely wrong (which could be the > case) I have identified two leading options for my case: > > > > 1) use a behaviour (perhaps improperly) as a pure interface (i.e., with > only callbacks and no "general" functionality). For a child implemented in > a `my_child_mod` module that implements behaviour `my_iface`, this could > result in calls like `my_iface:a_common_fun(ChildServerRef)` after fetching > the child server reference where I use the behaviour's module to access the > child's functionality... OR > > > > 2) store the particular module of each child with the reference and use > the stored module name at time of the call (and know/assume that all > children have some shared functionality). So using some tuple or similar > `{my_child_mod, ChildServerRef}` (versus just the reference) could result > in a call like `my_child_mod:a_common_fun(ChildServerRef)` after fetching > the reference info (as a tuple). > > > > I, perhaps naively, gravitate towards #1 above for various reasons > (compile-time checks, only having to carry around refs, my C++ background, > etc.), but the internet (and ferd in particular here ( > https://stackoverflow.com/questions/4119477/implementing-interfaces-in-erlang/4119615#4119615)) > seems to imply that this is not the Erlang way (despite finding OTP cases > like this: > https://github.com/erlang/otp/blob/master/lib/ssh/src/ssh_sftpd_file_api.erl). > ... shame on me? > > > > > > I am trying very hard to leave my C++ past behind and do things in the > Erlang way, but need a little help in this particular case... > > > > Thanks, > > Brett > -------------- next part -------------- An HTML attachment was scrubbed... URL: From empro2@REDACTED Tue Aug 24 14:57:32 2021 From: empro2@REDACTED (Michael P.) Date: Tue, 24 Aug 2021 14:57:32 +0200 Subject: A case of misunderstandings (was: What use is `case` [...]) In-Reply-To: <20210818140410.697a49ff@aesop> References: <20210818140410.697a49ff@aesop> Message-ID: <20210824145732.5270aa6b@aesop> Hello there, On Sun, 22 Aug 2021 19:59:51 +1200 "Richard O'Keefe" wrote: > The use of words like "sneak" sets up a rather hostile tone. To each and any, please, simply tell me just like that. Such is so far from me that it slips through my extensive "reflection framework" -- and I do pay attention to connotation but ... I had been "lurking" on this list for two years (or such) before subscribing, plucking Erlang puzzles from the archive, guessing answers, guessing who might say what. That might have created a subconscious, illusive "familiarity". So, I post again: Alas! my English _looks_ better than it _is_. I think I have finally managed to trace it mostly back to two misunderstandings leading to two misconceptions leading to ... this. I have decided to split this from the explanation, due to urgency. (... or the explanation from this ...? no, this is smaller, but ...) "Slay not he who cannot hear Be thankful ye that hast an ear." ~Michael -- Curiosity killed the cat -- by simply using up its time. From brhemes@REDACTED Tue Aug 24 23:46:30 2021 From: brhemes@REDACTED (Brett Hemes) Date: Tue, 24 Aug 2021 21:46:30 +0000 Subject: I am close to using a behaviour as a pure interface and I feel dirty... Message-ID: > Erlang's behaviour is NOT an interface! > If you are looking for some analogy from other languages the closest one is abstract classes in C#. This isn?t very helpful... it is the exact same response I find in the forums with no reasoning behind it. I don?t need analogies either; I understand what behaviours are ?supposed? to be from the documentation and comments (perhaps this wasn?t made clear by my post). Where I fall short is ?why? are behaviours limited to such and why aren?t more people asking the same questions I am stuck on (regarding polymorphism)? My logic was: yes, this has been asked and discussed some in the past with no real resolution that I could find... therefore, users must be content/accepting of the tools provided. I am not so naive to think I am the first to need/want such, so there must be a disconnect. I posted my example to motivate my questioning hoping for some insight and/or comfort. As of now, I have proceeded with storing ?meta refs? to my child servers that are module/reference tuples (along with some dangerous and future-maintenance-issue-causing assumptions regarding their ?interface?)... and it?s works... it just smells, and I am always eager to learn and find the right/better/best way. Aside: a colleague came across this repo (https://github.com/eldarko/epolymorph) while digging and the readme seems to capture my use case almost exactly... Brett -------------- next part -------------- An HTML attachment was scrubbed... URL: From elbrujohalcon@REDACTED Tue Aug 24 23:53:55 2021 From: elbrujohalcon@REDACTED (Fernando Benavides) Date: Tue, 24 Aug 2021 23:53:55 +0200 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: I'm not entirely sure if this will help but a while back I wrote two articles and gave a talk about this subject. But I might have faced it from a different angle. These are the links: - https://youtu.be/OWCYD1Q0COQ - https://medium.com/erlang-battleground/erlang-behaviors-4348e89351ff - https://medium.com/erlang-battleground/erlang-behaviors-d5bb30d5412b On Tue, 24 Aug 2021 at 23:47 Brett Hemes wrote: > > Erlang's behaviour is NOT an interface! > > > If you are looking for some analogy from other languages the closest one > is abstract classes in C#. > > > > This isn?t very helpful... it is the exact same response I find in the > forums with no reasoning behind it. I don?t need analogies either; I > understand what behaviours are ?supposed? to be from the documentation and > comments (perhaps this wasn?t made clear by my post). Where I fall short > is ?why? are behaviours limited to such and why aren?t more people asking > the same questions I am stuck on (regarding polymorphism)? My logic was: > yes, this has been asked and discussed some in the past with no real > resolution that I could find... therefore, users must be content/accepting > of the tools provided. I am not so naive to think I am the first to > need/want such, so there must be a disconnect. > > > > I posted my example to motivate my questioning hoping for some insight > and/or comfort. As of now, I have proceeded with storing ?meta refs? to my > child servers that are module/reference tuples (along with some dangerous > and future-maintenance-issue-causing assumptions regarding their > ?interface?)... and it?s works... it just smells, and I am always eager to > learn and find the right/better/best way. > > > > Aside: a colleague came across this repo ( > https://github.com/eldarko/epolymorph) while digging and the readme seems > to capture my use case almost exactly... > > > > Brett > -- Sent from Gmail Mobile by Brujo Benavides -------------- next part -------------- An HTML attachment was scrubbed... URL: From brhemes@REDACTED Wed Aug 25 00:13:08 2021 From: brhemes@REDACTED (Brett Hemes) Date: Tue, 24 Aug 2021 22:13:08 +0000 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: Brujo! Yes I read both of these (and your other stuff too) some time back and they have been (and still are) very helpful on my journey. I just watched the presentation earlier today coincidentally in my search and it confirmed most of what I have learned but still doesn?t tackle my deeper questions like (?am I doing something stupid to even arrive at this line of questioning?? and ?why shouldn?t I have a delegate behaviour and/or one of just callbacks??, etc.). Thanks! Brett From: Fernando Benavides Sent: Tuesday, August 24, 2021 4:54 PM To: Brett Hemes Cc: erlang-questions@REDACTED Subject: [EXTERNAL] Re: Re: I am close to using a behaviour as a pure interface and I feel dirty... I'm not entirely sure if this will help but a while back I wrote two articles and gave a talk about this subject. But I might have faced it from a different angle. These are the links: - https://youtu.be/OWCYD1Q0COQ - https://medium.com/erlang-battleground/erlang-behaviors-4348e89351ff - https://medium.com/erlang-battleground/erlang-behaviors-d5bb30d5412b On Tue, 24 Aug 2021 at 23:47 Brett Hemes > wrote: > Erlang's behaviour is NOT an interface! > If you are looking for some analogy from other languages the closest one is abstract classes in C#. This isn?t very helpful... it is the exact same response I find in the forums with no reasoning behind it. I don?t need analogies either; I understand what behaviours are ?supposed? to be from the documentation and comments (perhaps this wasn?t made clear by my post). Where I fall short is ?why? are behaviours limited to such and why aren?t more people asking the same questions I am stuck on (regarding polymorphism)? My logic was: yes, this has been asked and discussed some in the past with no real resolution that I could find... therefore, users must be content/accepting of the tools provided. I am not so naive to think I am the first to need/want such, so there must be a disconnect. I posted my example to motivate my questioning hoping for some insight and/or comfort. As of now, I have proceeded with storing ?meta refs? to my child servers that are module/reference tuples (along with some dangerous and future-maintenance-issue-causing assumptions regarding their ?interface?)... and it?s works... it just smells, and I am always eager to learn and find the right/better/best way. Aside: a colleague came across this repo (https://github.com/eldarko/epolymorph) while digging and the readme seems to capture my use case almost exactly... Brett -- Sent from Gmail Mobile by Brujo Benavides -------------- next part -------------- An HTML attachment was scrubbed... URL: From s.ledenev@REDACTED Wed Aug 25 11:03:40 2021 From: s.ledenev@REDACTED (Stanislav Ledenev) Date: Wed, 25 Aug 2021 12:03:40 +0300 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: OK, I'll try to give you my opinion on this topic. If I understand your question correctly. It may look rude but please believe me it is not my intention to be rude. Your examples for me are the evidence of the "classic OOP" poisoning. Remark: I call it "classic" based on how the vast majority of the developers perceive the idea of objects and interaction between them. Though I am on the side of Alan Kay's definition of the OOP - objects communicating with messages. Anyway, how you "slice" the world and how you make your abstractions - it is influenced by the "classic OOP". Erlang is the functional language (more or less) so abstractions are made the other way: 1. Basic units are Module and Function; 2. Dynamic function calls - Module:Function(Args). So you can dynamically (in runtime) change the module; 3. Behaviour is just a hint for a compiler to check a Module for a presence of the required functions. Based on these 3 points - when you write -behaviour(....) in a module you are just saying that this module must have a bunch of functions implemented to be successfully compiled. It is not for supporting your own abstractions. It is an instrument to remind you to implement functions. What you call "general" functionality in Erlang is simply a library implemented as module(s). Of course it is very tempting to call behaviour an interface, because it looks like an interface. But it is not because the interface in Erlang are the functions, not a separate entity. Example of using behaviour from my own experience. As in almost any application I must have something where I store the data. And requirements are very vague. So I don't know if it would be Mnesia, PostgreSQL, file, space station or a toaster. So I've made the behaviour which defines functions for my business logic associated with storage. To make it simple it is like the CRUD operations on my entities. This behaviour is implemented as an independent rebar3 library, so other parties (sometimes remote) can include it as a dependency. But their implementations are included in the final application and what implementation will be used is defined in the configuration file. (Pseudo) code is like this: callbacks_db.erl: -module(callbacks_db). -callback create(Entity::my_entity_t()) -> ok | {error, Result :: term()}. postgresql.erl: -module(postgresql). -behaviour(callbacks_db). create(Entity) -> .... toaster_able_to_storage_data.erl: -module(toaster_able_to_storage_data). -behaviour(callbacks_db). create(Entity) -> .... main_app.config: {main_app, [ {db, #{mod => postgresql}} % If you are using a toaster use "toaster_able_to_storage_data" ]} main_app.erl: some_function(DBMod) -> Entity = create_entity(...), DBmod:create(Entity). That is all about behaviour. ??, 25 ???. 2021 ?. ? 00:46, Brett Hemes : > > Erlang's behaviour is NOT an interface! > > > If you are looking for some analogy from other languages the closest one > is abstract classes in C#. > > > > This isn?t very helpful... it is the exact same response I find in the > forums with no reasoning behind it. I don?t need analogies either; I > understand what behaviours are ?supposed? to be from the documentation and > comments (perhaps this wasn?t made clear by my post). Where I fall short > is ?why? are behaviours limited to such and why aren?t more people asking > the same questions I am stuck on (regarding polymorphism)? My logic was: > yes, this has been asked and discussed some in the past with no real > resolution that I could find... therefore, users must be content/accepting > of the tools provided. I am not so naive to think I am the first to > need/want such, so there must be a disconnect. > > > > I posted my example to motivate my questioning hoping for some insight > and/or comfort. As of now, I have proceeded with storing ?meta refs? to my > child servers that are module/reference tuples (along with some dangerous > and future-maintenance-issue-causing assumptions regarding their > ?interface?)... and it?s works... it just smells, and I am always eager to > learn and find the right/better/best way. > > > > Aside: a colleague came across this repo ( > https://github.com/eldarko/epolymorph) while digging and the readme seems > to capture my use case almost exactly... > > > > Brett > -------------- next part -------------- An HTML attachment was scrubbed... URL: From t@REDACTED Wed Aug 25 13:41:53 2021 From: t@REDACTED (Tristan Sloughter) Date: Wed, 25 Aug 2021 05:41:53 -0600 Subject: =?UTF-8?Q?Re:_I_am_close_to_using_a_behaviour_as_a_pure_interface_and_I_?= =?UTF-8?Q?feel_dirty...?= In-Reply-To: References: Message-ID: I'll drop in this effort that was made years ago: https://github.com/erlware/erlware_commons/blob/master/doc/signatures.md But I'm not saying I recommend it, I don't know that it is used much and I'd like to deprecate erlware_commons in the not too distant future (it is a dependency used by rebar3/relx and we want to remove as many of those as possible). I'll also point out my use of behaviours to provide APIs for functionality (an Application Programming INTERFACE -- so "interface" isn't always an OOP construct). Hah, just realized I even called it an "interface" in my most recent PR https://github.com/open-telemetry/opentelemetry-erlang/pull/269 On Tue, Aug 24, 2021, at 15:46, Brett Hemes wrote: > > Erlang's behaviour is NOT an interface! > > If you are looking for some analogy from other languages the closest one is abstract classes in C#. > > This isn?t very helpful... it is the exact same response I find in the forums with no reasoning behind it. I don?t need analogies either; I understand what behaviours are ?supposed? to be from the documentation and comments (perhaps this wasn?t made clear by my post). Where I fall short is ?why? are behaviours limited to such and why aren?t more people asking the same questions I am stuck on (regarding polymorphism)? My logic was: yes, this has been asked and discussed some in the past with no real resolution that I could find... therefore, users must be content/accepting of the tools provided. I am not so naive to think I am the first to need/want such, so there must be a disconnect. > > I posted my example to motivate my questioning hoping for some insight and/or comfort. As of now, I have proceeded with storing ?meta refs? to my child servers that are module/reference tuples (along with some dangerous and future-maintenance-issue-causing assumptions regarding their ?interface?)... and it?s works... it just smells, and I am always eager to learn and find the right/better/best way. > > Aside: a colleague came across this repo (https://github.com/eldarko/epolymorph) while digging and the readme seems to capture my use case almost exactly... > > Brett -------------- next part -------------- An HTML attachment was scrubbed... URL: From brhemes@REDACTED Wed Aug 25 17:30:55 2021 From: brhemes@REDACTED (Brett Hemes) Date: Wed, 25 Aug 2021 15:30:55 +0000 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: Historically, have there ever been discussion of including stuff like this in the language itself? Brett From: erlang-questions On Behalf Of Tristan Sloughter Sent: Wednesday, August 25, 2021 6:42 AM To: Erlang Questions Subject: [EXTERNAL] Re: I am close to using a behaviour as a pure interface and I feel dirty... I'll drop in this effort that was made years ago: https://github.com/erlware/erlware_commons/blob/master/doc/signatures.md But I'm not saying I recommend it, I don't know that it is used much and I'd like to deprecate erlware_commons in the not too distant future (it is a dependency used by rebar3/relx and we want to remove as many of those as possible). I'll also point out my use of behaviours to provide APIs for functionality (an Application Programming INTERFACE -- so "interface" isn't always an OOP construct). Hah, just realized I even called it an "interface" in my most recent PR https://github.com/open-telemetry/opentelemetry-erlang/pull/269 On Tue, Aug 24, 2021, at 15:46, Brett Hemes wrote: > Erlang's behaviour is NOT an interface! > If you are looking for some analogy from other languages the closest one is abstract classes in C#. This isn?t very helpful... it is the exact same response I find in the forums with no reasoning behind it. I don?t need analogies either; I understand what behaviours are ?supposed? to be from the documentation and comments (perhaps this wasn?t made clear by my post). Where I fall short is ?why? are behaviours limited to such and why aren?t more people asking the same questions I am stuck on (regarding polymorphism)? My logic was: yes, this has been asked and discussed some in the past with no real resolution that I could find... therefore, users must be content/accepting of the tools provided. I am not so naive to think I am the first to need/want such, so there must be a disconnect. I posted my example to motivate my questioning hoping for some insight and/or comfort. As of now, I have proceeded with storing ?meta refs? to my child servers that are module/reference tuples (along with some dangerous and future-maintenance-issue-causing assumptions regarding their ?interface?)... and it?s works... it just smells, and I am always eager to learn and find the right/better/best way. Aside: a colleague came across this repo (https://github.com/eldarko/epolymorph) while digging and the readme seems to capture my use case almost exactly... Brett -------------- next part -------------- An HTML attachment was scrubbed... URL: From brhemes@REDACTED Wed Aug 25 17:33:23 2021 From: brhemes@REDACTED (Brett Hemes) Date: Wed, 25 Aug 2021 15:33:23 +0000 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: Thank you Stanislav for taking the time to iterate. This is nice. > Though I am on the side of Alan Kay's definition of the OOP - objects communicating with messages. > Anyway, how you "slice" the world and how you make your abstractions - it is influenced by the "classic OOP". > Of course it is very tempting to call behaviour an interface, because it looks like an interface. > But it is not because the interface in Erlang are the functions, not a separate entity. Indeed, but all of the teaching texts are very quick to advocate wrapping your implementations with API calls that delegate to the underlying implementation. This in my mind adds a layer of abstraction on top of pure message passing... abstractions that play to the weaknesses of "poisoned" practitioners ;) That said, your answer does help; thank you again very much! I am still not all the way there yet, but at a much better place than a few days ago. My current impression at this point is that the topic is nuanced and perhaps I should be thinking more along the lines of "quit THINKING of behaviours in terms of interfaces" or more generally, "quit THINIKING in terms of interfaces at all"? I found it interesting in your example you call `create/1` in main_app at runtime using `DBmod` where my misguided thinking would have tried to use `callbacks_db` instead (interface thinking). ...this might be my disconnect. > It is an instrument to remind you to implement functions. As I type this I think most of my issues stem from the fear of changing something in the future and not having compile-time checks to help me find all the references (and I saw the behaviour as a nice compile-time check (crutch?) that looked attractive). This is probably a bigger and different issue all together that I need to learn more about within the Erlang ecosystem. I am assuming it is some combination of supervision, Dialyzer, and really good tests but I am sure I will learn this quite quickly after deploying some real stuff in the wild... I just would rather learn as much as I can before that time comes. Thanks, Brett From: Stanislav Ledenev Sent: Wednesday, August 25, 2021 4:04 AM To: Brett Hemes Cc: erlang-questions@REDACTED Subject: [EXTERNAL] Re: Re: I am close to using a behaviour as a pure interface and I feel dirty... OK, I'll try to give you my opinion on this topic. If I understand your question correctly. It may look rude but please believe me it is not my intention to be rude. Your examples for me are the evidence of the "classic OOP" poisoning. Remark: I call it "classic" based on how the vast majority of the developers perceive the idea of objects and interaction between them. Though I am on the side of Alan Kay's definition of the OOP - objects communicating with messages. Anyway, how you "slice" the world and how you make your abstractions - it is influenced by the "classic OOP". Erlang is the functional language (more or less) so abstractions are made the other way: 1. Basic units are Module and Function; 2. Dynamic function calls - Module:Function(Args). So you can dynamically (in runtime) change the module; 3. Behaviour is just a hint for a compiler to check a Module for a presence of the required functions. Based on these 3 points - when you write -behaviour(....) in a module you are just saying that this module must have a bunch of functions implemented to be successfully compiled. It is not for supporting your own abstractions. It is an instrument to remind you to implement functions. What you call "general" functionality in Erlang is simply a library implemented as module(s). Of course it is very tempting to call behaviour an interface, because it looks like an interface. But it is not because the interface in Erlang are the functions, not a separate entity. Example of using behaviour from my own experience. As in almost any application I must have something where I store the data. And requirements are very vague. So I don't know if it would be Mnesia, PostgreSQL, file, space station or a toaster. So I've made the behaviour which defines functions for my business logic associated with storage. To make it simple it is like the CRUD operations on my entities. This behaviour is implemented as an independent rebar3 library, so other parties (sometimes remote) can include it as a dependency. But their implementations are included in the final application and what implementation will be used is defined in the configuration file. (Pseudo) code is like this: callbacks_db.erl: -module(callbacks_db). -callback create(Entity::my_entity_t()) -> ok | {error, Result :: term()}. postgresql.erl: -module(postgresql). -behaviour(callbacks_db). create(Entity) -> .... toaster_able_to_storage_data.erl: -module(toaster_able_to_storage_data). -behaviour(callbacks_db). create(Entity) -> .... main_app.config: {main_app, [ {db, #{mod => postgresql}} % If you are using a toaster use "toaster_able_to_storage_data" ]} main_app.erl: some_function(DBMod) -> Entity = create_entity(...), DBmod:create(Entity). That is all about behaviour. ??, 25 ???. 2021 ?. ? 00:46, Brett Hemes >: > Erlang's behaviour is NOT an interface! > If you are looking for some analogy from other languages the closest one is abstract classes in C#. This isn?t very helpful... it is the exact same response I find in the forums with no reasoning behind it. I don?t need analogies either; I understand what behaviours are ?supposed? to be from the documentation and comments (perhaps this wasn?t made clear by my post). Where I fall short is ?why? are behaviours limited to such and why aren?t more people asking the same questions I am stuck on (regarding polymorphism)? My logic was: yes, this has been asked and discussed some in the past with no real resolution that I could find... therefore, users must be content/accepting of the tools provided. I am not so naive to think I am the first to need/want such, so there must be a disconnect. I posted my example to motivate my questioning hoping for some insight and/or comfort. As of now, I have proceeded with storing ?meta refs? to my child servers that are module/reference tuples (along with some dangerous and future-maintenance-issue-causing assumptions regarding their ?interface?)... and it?s works... it just smells, and I am always eager to learn and find the right/better/best way. Aside: a colleague came across this repo (https://github.com/eldarko/epolymorph) while digging and the readme seems to capture my use case almost exactly... Brett -------------- next part -------------- An HTML attachment was scrubbed... URL: From ifl21.publicity@REDACTED Wed Aug 25 18:10:47 2021 From: ifl21.publicity@REDACTED (Pieter Koopman) Date: Wed, 25 Aug 2021 09:10:47 -0700 Subject: IFL'21 call for participation Message-ID: ================================================================================ IFL 2021 33rd Symposium on Implementation and Application of Functional Languages venue: online 1 - 3 September 2021 https://ifl21.cs.ru.nl *Registration* Registration is free of charge, but required for participation! Use the below link to register for IFL 2021: https://docs.google.com/forms/d/e/1FAIpQLSdMFjo-GumKjk4i7szs7n4DhWqKt96t8ofIqshfQFrf4jnvsA/viewform?usp=sf_link *Scope* The goal of the IFL symposia is to bring together researchers actively engaged in the implementation and application of functional and function-based programming languages. IFL 2021 will be a venue for researchers to present and discuss new ideas and concepts, work in progress, and publication-ripe results related to the implementation and application of functional languages and function-based programming. *Program* The program is now available at https://ifl21.cs.ru.nl/Program . *Organisation* IFL 2021 Chairs: Pieter Koopman and Peter Achten, Radboud University, The Netherlands IFL Publicity chair: Pieter Koopman, Radboud University, The Netherlands *PC* Peter Achten (co-chair) - Radboud University, Netherlands Thomas van Binsbergen - University of Amsterdam, Netherlands Edwin Brady - University of St. Andrews, Scotland Laura Castro - University of A Coru?a, Spain Youyou Cong - Tokyo Institute of Technology, Japan Olaf Chitil - University of Kent, England Andy Gill - University of Kansas, USA Clemens Grelck - University of Amsterdam, Netherlands John Hughes - Chalmers University, Sweden Pieter Koopman (co-chair) - Radboud University, Netherlands Cynthia Kop - Radboud University, Netherlands Jay McCarthey - University of Massachussetts Lowell, USA Neil Mitchell - Facebook, England Jan De Muijnck-Hughes - Glasgow University, Scotland Keiko Nakata - SAP Innovation Center Potsdam, Germany Jurri?n Stutterheim - Standard Chartered, Singapore Simon Thompson - University of Kent, England Melinda T?th - E?tvos Lor?nd University, Hungary Phil Trinder - Glasgow University, Scotland Meng Wang - University of Bristol, England Vikt?ria Zs?k - E?tvos Lor?nd University, Hungary [image: beacon] -------------- next part -------------- An HTML attachment was scrubbed... URL: From s.ledenev@REDACTED Thu Aug 26 09:27:43 2021 From: s.ledenev@REDACTED (Stanislav Ledenev) Date: Thu, 26 Aug 2021 10:27:43 +0300 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: You are welcome! >> I am still not all the way there yet, but at a much better place than a few days ago. >> My current impression at this point is that the topic is nuanced and >> perhaps I should be thinking more along the lines of >> "quit THINKING of behaviours in terms of interfaces" or more generally, >> "quit THINIKING in terms of interfaces at all"? I don't think we can put the idea of "interface" away at all. We are surrounded by "interfaces" in real life. For instance, the power outlet and electrical plug is the interface. I'd rather say that it is better to go away from OOP's definition of interface to more practical one. I'd say that the set of exported functions in the module is the interface too. And of course to get rid of unnecessary layers of abstractions. As Joe Armstrong said: "The problem with object-oriented languages is they?ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle." >> As I type this I think most of my issues stem from the fear of changing >> something in the future and not having compile-time checks to help me find >> all the references (and I saw the behaviour as a nice compile-time check >> (crutch?) that looked attractive). This is probably a bigger and different >> issue all together that I need to learn more about within the Erlang ecosystem. >> I am assuming it is some combination of supervision, Dialyzer, and really good tests but >> I am sure I will learn this quite quickly after deploying some real stuff in the wild... >> I just would rather learn as much as I can before that time comes. I highly recommend you to go deeper into the Erlang ecosystem. The process of transition from other languages to the Erlang is much steeper than with other languages but definitely more rewarding. And I would recommend spending more time with tools but be careful though. For example, due to dynamic nature of the language you write in your code something like this: foo() -> Result = hjsdfkjsdhfskjfhskhskhfskl:yutyrutyriuyiw(), ... And it will compile. Because you can bring the module "hjsdfkjsdhfskjfhskhskhfskl" later and the compiler doesn't know that. And the Dialyzer won't tell you anything... But the "xref" tool may tell you that you are probably using an unknown function in an unknown module. ??, 25 ???. 2021 ?. ? 18:33, Brett Hemes : > Thank you Stanislav for taking the time to iterate. This is nice. > > > > > Though I am on the side of Alan Kay's definition of the OOP - objects > communicating with messages. > > > > > Anyway, how you "slice" the world and how you make your abstractions - > it is influenced by the "classic OOP". > > > > > Of course it is very tempting to call behaviour an interface, because it > looks like an interface. > > > But it is not because the interface in Erlang are the functions, not a > separate entity. > > > > Indeed, but all of the teaching texts are very quick to advocate wrapping > your implementations with API calls that delegate to the underlying > implementation. This in my mind adds a layer of abstraction on top of pure > message passing... abstractions that play to the weaknesses of "poisoned" > practitioners ;) > > > > That said, your answer does help; thank you again very much! > > > > I am still not all the way there yet, but at a much better place than a > few days ago. My current impression at this point is that the topic is > nuanced and perhaps I should be thinking more along the lines of "quit > THINKING of behaviours in terms of interfaces" or more generally, "quit > THINIKING in terms of interfaces at all"? > > > > I found it interesting in your example you call `create/1` in main_app at > runtime using `DBmod` where my misguided thinking would have tried to use > `callbacks_db` instead (interface thinking). ...this might be my > disconnect. > > > > > It is an instrument to remind you to implement functions. > > > > As I type this I think most of my issues stem from the fear of changing > something in the future and not having compile-time checks to help me find > all the references (and I saw the behaviour as a nice compile-time check > (crutch?) that looked attractive). This is probably a bigger and different > issue all together that I need to learn more about within the Erlang > ecosystem. I am assuming it is some combination of supervision, Dialyzer, > and really good tests but I am sure I will learn this quite quickly after > deploying some real stuff in the wild... I just would rather learn as much > as I can before that time comes. > > > > > > Thanks, > > Brett > > > > > > *From:* Stanislav Ledenev > *Sent:* Wednesday, August 25, 2021 4:04 AM > *To:* Brett Hemes > *Cc:* erlang-questions@REDACTED > *Subject:* [EXTERNAL] Re: Re: I am close to using a behaviour as a pure > interface and I feel dirty... > > > > OK, I'll try to give you my opinion on this topic. If I understand > your question correctly. > > It may look rude but please believe me it is not my intention to be rude. > > > > Your examples for me are the evidence of the "classic OOP" poisoning. > > Remark: > > I call it "classic" based on how the vast majority of the developers > perceive the idea of objects and > > interaction between them. > > Though I am on the side of Alan Kay's definition of the OOP - objects > communicating with messages. > > > > Anyway, how you "slice" the world and how you make your abstractions - it > is influenced by the "classic OOP". > > Erlang is the functional language (more or less) so abstractions are made > the other way: > > 1. Basic units are Module and Function; > > 2. Dynamic function calls - Module:Function(Args). So you can dynamically > (in runtime) change the module; > > 3. Behaviour is just a hint for a compiler to check a Module for a > presence of the required functions. > > > > Based on these 3 points - when you write -behaviour(....) in a module you > are just saying that > > this module must have a bunch of functions implemented to be successfully > compiled. It is not for > > supporting your own abstractions. It is an instrument to remind you to > implement functions. > > > > What you call "general" functionality in Erlang is simply a library > implemented as module(s). > > > > Of course it is very tempting to call behaviour an interface, because it > looks like an interface. > > But it is not because the interface in Erlang are the functions, not a > separate entity. > > > > Example of using behaviour from my own experience. > > As in almost any application I must have something where I store the data. > > And requirements are very vague. So I don't know if it would be Mnesia, > PostgreSQL, file, space station or a toaster. > > So I've made the behaviour which defines functions for my business logic > associated with storage. > > To make it simple it is like the CRUD operations on my entities. > > This behaviour is implemented as an independent rebar3 library, so other > parties (sometimes remote) can include it as a dependency. > > But their implementations are included in the final application and what > implementation will be used > > is defined in the configuration file. > > (Pseudo) code is like this: > > > > callbacks_db.erl: > > -module(callbacks_db). > > -callback create(Entity::my_entity_t()) -> ok | {error, Result :: > term()}. > > > > postgresql.erl: > > -module(postgresql). > > -behaviour(callbacks_db). > > create(Entity) -> .... > > > > toaster_able_to_storage_data.erl: > > -module(toaster_able_to_storage_data). > > -behaviour(callbacks_db). > > create(Entity) -> .... > > > > main_app.config: > > {main_app, [ > > {db, #{mod => postgresql}} % If you are using a toaster use > "toaster_able_to_storage_data" > > ]} > > > > main_app.erl: > > some_function(DBMod) -> > > Entity = create_entity(...), > > DBmod:create(Entity). > > > > That is all about behaviour. > > > > ??, 25 ???. 2021 ?. ? 00:46, Brett Hemes : > > > Erlang's behaviour is NOT an interface! > > > If you are looking for some analogy from other languages the closest one > is abstract classes in C#. > > > > This isn?t very helpful... it is the exact same response I find in the > forums with no reasoning behind it. I don?t need analogies either; I > understand what behaviours are ?supposed? to be from the documentation and > comments (perhaps this wasn?t made clear by my post). Where I fall short > is ?why? are behaviours limited to such and why aren?t more people asking > the same questions I am stuck on (regarding polymorphism)? My logic was: > yes, this has been asked and discussed some in the past with no real > resolution that I could find... therefore, users must be content/accepting > of the tools provided. I am not so naive to think I am the first to > need/want such, so there must be a disconnect. > > > > I posted my example to motivate my questioning hoping for some insight > and/or comfort. As of now, I have proceeded with storing ?meta refs? to my > child servers that are module/reference tuples (along with some dangerous > and future-maintenance-issue-causing assumptions regarding their > ?interface?)... and it?s works... it just smells, and I am always eager to > learn and find the right/better/best way. > > > > Aside: a colleague came across this repo ( > https://github.com/eldarko/epolymorph) while digging and the readme seems > to capture my use case almost exactly... > > > > Brett > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kostis@REDACTED Thu Aug 26 09:45:29 2021 From: kostis@REDACTED (Kostis Sagonas) Date: Thu, 26 Aug 2021 09:45:29 +0200 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: On 8/26/21 9:27 AM, Stanislav Ledenev wrote: > And I would recommend spending more time with tools but be careful though. Yes, both of these are good pieces of advice. The second is also applicable to what one writes about the tools of the Erlang ecosystem. > For example, due to dynamic nature of the language you write in your > code something > like this: > ? ? foo() -> > ? ? ? ? Result = hjsdfkjsdhfskjfhskhskhfskl:yutyrutyriuyiw(), > ? ? ? ? ... > > And it will compile. Because you can bring the module > "hjsdfkjsdhfskjfhskhskhfskl" later > and the compiler doesn't know that. And the Dialyzer won't tell you > anything... > But the "xref" tool may tell you that you are probably using an unknown > function in an unknown module. Surely Dialyzer will tell you that there is an unknown function in the module that you analyze. Other than speed, there is no reason to use 'xref' for this simple task. Kostis From s.ledenev@REDACTED Thu Aug 26 15:18:31 2021 From: s.ledenev@REDACTED (Stanislav Ledenev) Date: Thu, 26 Aug 2021 16:18:31 +0300 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: >> Surely Dialyzer will tell you that there is an unknown function in the >> module that you analyze. I guess you are talking about the -Wunknown option? It is ok, but this option is turned off by default. At the beginning of learning Erlang's tools, in terms of ease of use, the xref tool is more convenient (IMHO of course). Anyway, Erlang has a bunch of really good tools and understanding them is a matter of time. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From t@REDACTED Thu Aug 26 18:01:12 2021 From: t@REDACTED (Tristan Sloughter) Date: Thu, 26 Aug 2021 10:01:12 -0600 Subject: =?UTF-8?Q?Re:_I_am_close_to_using_a_behaviour_as_a_pure_interface_and_I_?= =?UTF-8?Q?feel_dirty...?= In-Reply-To: References: Message-ID: I don't remember details and haven't reread this, but I dug up this old discussion about rebar3 and dialyzer unknown option: https://github.com/erlang/rebar3/issues/1751 Apparently the dialyzer cli tool has `-Wunknown` on by default but the api doesn't? On Thu, Aug 26, 2021, at 07:18, Stanislav Ledenev wrote: > >> Surely Dialyzer will tell you that there is an unknown function in the > >> module that you analyze. > > I guess you are talking about the -Wunknown option? > It is ok, but this option is turned off by default. > At the beginning of learning Erlang's tools, in terms of ease of use, the xref tool is more convenient (IMHO of course). > > Anyway, Erlang has a bunch of really good tools and understanding them is a matter of time. > > >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From s.ledenev@REDACTED Thu Aug 26 23:05:41 2021 From: s.ledenev@REDACTED (Stanislav Ledenev) Date: Fri, 27 Aug 2021 00:05:41 +0300 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: >> Apparently the dialyzer cli tool has `-Wunknown` on by default but the api doesn't? Quote (https://erlang.org/doc/man/dialyzer.html): " -Wunknown (***) Let warnings about unknown functions and types affect the exit status of the command-line version. The default is to ignore warnings about unknown functions and types when setting the exit status. When using Dialyzer from Erlang, warnings about unknown functions and types are returned; the default is not to return these warnings. *** denotes options that turn on warnings rather than turning them off. " ??, 26 ???. 2021 ?. ? 19:01, Tristan Sloughter : > I don't remember details and haven't reread this, but I dug up this old > discussion about rebar3 and dialyzer unknown option: > https://github.com/erlang/rebar3/issues/1751 > > Apparently the dialyzer cli tool has `-Wunknown` on by default but the api > doesn't? > > On Thu, Aug 26, 2021, at 07:18, Stanislav Ledenev wrote: > > >> Surely Dialyzer will tell you that there is an unknown function in the > >> module that you analyze. > > I guess you are talking about the -Wunknown option? > It is ok, but this option is turned off by default. > At the beginning of learning Erlang's tools, in terms of ease of use, the > xref tool is more convenient (IMHO of course). > > Anyway, Erlang has a bunch of really good tools and understanding them is > a matter of time. > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kostis@REDACTED Fri Aug 27 14:29:58 2021 From: kostis@REDACTED (Kostis Sagonas) Date: Fri, 27 Aug 2021 14:29:58 +0200 Subject: I am close to using a behaviour as a pure interface and I feel dirty... In-Reply-To: References: Message-ID: The statement in the manual is indeed a bit confusing, but it clearly states that enabling this option affects **the exit status** of the dialyzer Unix command. But dialyzer reports (and always reported) unknown functions, as you can see in the example it was mentioned in the beginning of this thread: $ dialyzer f.erl Checking whether the PLT /home/kostis/.dialyzer_plt is up-to-date... yes Proceeding with analysis... Unknown functions: hjsdfkjsdhfskjfhskhskhfskl:yutyrutyriuyiw/0 done in 0m1.41s done (passed successfully) Note the "passed successfully" exit status (since I did not use -Wunknown). If I use it, I get: $ dialyzer -Wunknown f.erl Checking whether the PLT /home/kostis/.dialyzer_plt is up-to-date... yes Proceeding with analysis... Unknown functions: hjsdfkjsdhfskjfhskhskhfskl:yutyrutyriuyiw/0 done in 0m1.02s done (warnings were emitted) I hope this settles it. But, if anybody from OTP reads this, perhaps the phrase: "; the default is not to return these warnings" should be taken out from the manual. Kostis On 8/26/21 11:05 PM, Stanislav Ledenev wrote: > >> Apparently the dialyzer cli tool has `-Wunknown` on by default but > the api doesn't? > > Quote (https://erlang.org/doc/man/dialyzer.html): > " > -Wunknown (***) > Let warnings about unknown functions and types affect the exit status of > the command-line version. The default is to ignore warnings about > unknown functions and types when setting the exit status. When using > Dialyzer from Erlang, warnings about unknown functions and types are > returned; the default is not to return these warnings. > > *** denotes options that turn on warnings rather than turning them off. > " > > ??, 26 ???. 2021 ?. ? 19:01, Tristan Sloughter >: > > __ > I don't remember details and haven't reread this, but I dug up this > old discussion about rebar3 and dialyzer unknown option: > https://github.com/erlang/rebar3/issues/1751 > > Apparently the dialyzer cli tool has `-Wunknown` on by default but > the api doesn't? > > On Thu, Aug 26, 2021, at 07:18, Stanislav Ledenev wrote: >> >> Surely Dialyzer will tell you that there is an unknown function >> in the >> >> module that you analyze. >> >> I guess you are talking about the?-Wunknown option? >> It is ok, but this option is turned off by default. >> At the beginning?of learning Erlang's tools, in terms of??ease of >> use, the xref tool is more convenient?(IMHO of course). >> >> Anyway, Erlang has a bunch of really good tools and understanding >> them is a matter of time. >> >> >> > From me@REDACTED Sun Aug 29 02:29:28 2021 From: me@REDACTED (Justin Wood) Date: Sat, 28 Aug 2021 20:29:28 -0400 Subject: Extra Byte in TCP Stream Message-ID: Hello List! I am in the process of building out an encoder/decoder for the RTMP protocol. I am testing my application with two clients. OBS[0] (this is considered the best client software to use for live streaming) and rtmpdump[1] (this is considered the best way to test your server implementation). My problem is that when using OBS, everything works as expected (or maybe I just haven't noticed it yet). When I use rtmpdump, I am getting an extra byte (195 or C3 in hex) placed in my TCP stream. Normally I would blame the implentation, but I am not seeing this byte when viewing traffic within wireshark. I have also tested this this on two machines. On both machines the extra byte is the same but the placement of it varies depending on which machine I am using but is always in the same place. Through the help of someone in IRC, it LOOKS like this is happening at a packet boundary, but I am not overly knowledgeable about this, so that may not be the case. I am using gen_tcp directly and am inspecting the data before it gets placed into my application and I am seeing this extra byte. So I am not somehow adding it myself. If anyone has any suggestions on how I may be able to go about diagnosing this, I would be greatly appreciated. Justin [0] - https://github.com/obsproject/obs-studio [1] - https://rtmpdump.mplayerhq.hu/ From huss01@REDACTED Sun Aug 29 06:01:04 2021 From: huss01@REDACTED (=?UTF-8?Q?H=C3=A5kan_Huss?=) Date: Sun, 29 Aug 2021 06:01:04 +0200 Subject: Extra Byte in TCP Stream In-Reply-To: References: Message-ID: Maybe https://serverfault.com/questions/1034291/rtmp-tcp-extra-byte-in-packet can provide the answer? /H?kan Den s?n 29 aug. 2021 03:01Justin Wood skrev: > Hello List! > > I am in the process of building out an encoder/decoder for the RTMP > protocol. I am testing my application with two clients. OBS[0] (this is > considered the best client software to use for live streaming) and > rtmpdump[1] (this is considered the best way to test your server > implementation). > > My problem is that when using OBS, everything works as expected (or > maybe I just haven't noticed it yet). When I use rtmpdump, I am getting > an extra byte (195 or C3 in hex) placed in my TCP stream. Normally I > would blame the implentation, but I am not seeing this byte when viewing > traffic within wireshark. I have also tested this this on two machines. > On both machines the extra byte is the same but the placement of it > varies depending on which machine I am using but is always in the same > place. Through the help of someone in IRC, it LOOKS like this is > happening at a packet boundary, but I am not overly knowledgeable about > this, so that may not be the case. > > I am using gen_tcp directly and am inspecting the data before it gets > placed into my application and I am seeing this extra byte. So I am not > somehow adding it myself. > > If anyone has any suggestions on how I may be able to go about > diagnosing this, I would be greatly appreciated. > > Justin > > [0] - https://github.com/obsproject/obs-studio > [1] - https://rtmpdump.mplayerhq.hu/ > -------------- next part -------------- An HTML attachment was scrubbed... URL: From me@REDACTED Sun Aug 29 13:54:10 2021 From: me@REDACTED (Justin Wood) Date: Sun, 29 Aug 2021 07:54:10 -0400 Subject: Extra Byte in TCP Stream In-Reply-To: Message-ID: That does potentially sound like it could be my issue. Thank you, Justin On Sun Aug 29, 2021 at 12:01 AM EDT, H?kan Huss wrote: > Maybe > https://serverfault.com/questions/1034291/rtmp-tcp-extra-byte-in-packet > can > provide the answer? > > /H?kan > > Den s?n 29 aug. 2021 03:01Justin Wood skrev: > > > Hello List! > > > > I am in the process of building out an encoder/decoder for the RTMP > > protocol. I am testing my application with two clients. OBS[0] (this is > > considered the best client software to use for live streaming) and > > rtmpdump[1] (this is considered the best way to test your server > > implementation). > > > > My problem is that when using OBS, everything works as expected (or > > maybe I just haven't noticed it yet). When I use rtmpdump, I am getting > > an extra byte (195 or C3 in hex) placed in my TCP stream. Normally I > > would blame the implentation, but I am not seeing this byte when viewing > > traffic within wireshark. I have also tested this this on two machines. > > On both machines the extra byte is the same but the placement of it > > varies depending on which machine I am using but is always in the same > > place. Through the help of someone in IRC, it LOOKS like this is > > happening at a packet boundary, but I am not overly knowledgeable about > > this, so that may not be the case. > > > > I am using gen_tcp directly and am inspecting the data before it gets > > placed into my application and I am seeing this extra byte. So I am not > > somehow adding it myself. > > > > If anyone has any suggestions on how I may be able to go about > > diagnosing this, I would be greatly appreciated. > > > > Justin > > > > [0] - https://github.com/obsproject/obs-studio > > [1] - https://rtmpdump.mplayerhq.hu/ > > From max.lapshin@REDACTED Sun Aug 29 15:28:42 2021 From: max.lapshin@REDACTED (Max Lapshin) Date: Sun, 29 Aug 2021 16:28:42 +0300 Subject: Extra Byte in TCP Stream In-Reply-To: References: Message-ID: Yet another erlang rtmp implementation =) Maybe we should open ours some day. It is a 100% problem in your code, do not rely 100% on wireshark. I have some questions about the OBS rtmp implementation, but mostly it works ok. From g@REDACTED Mon Aug 30 02:43:40 2021 From: g@REDACTED (Guilherme Andrade) Date: Mon, 30 Aug 2021 01:43:40 +0100 Subject: [ANN] locus: Geolocation and ASN lookup of IP addresses In-Reply-To: References: Message-ID: Hello list, Locus 2.0.0, a MaxMind DB reader, was released tonight. Added: - support for retrieving databases using consumer-defined fetchers - support for decoding IEEE-754 infinities in MMDB data - `locus:check/1` to API (which replaces `locus:analyze/1` and can be up to 3200% faster) - details to MMDB unpacking errors - linting checks with `rebar3_lint` - dead code checks with `rebar3_hank` Changed: - ?? return type of `locus:lookup/2` (see MIGRATION.md) - database loader to use `persistent_term` instead of ETS - MMDB decoder to perform stricter metadata validations - MMDB decoder to not crash upon maps containing duplicate keys - databases downloaded through HTTP(S) without a `last-modified` response header to no longer be cached - imported version of `tls_certificate_check` to '~> 1.7' - single CT suite covering both filesystem and HTTP sources into one for each - test coverage for the better Removed: - ?? `locus:wait_for_loader/1` from API (deprecated in 1.10.0 - see MIGRATION.md) - ?? `locus:wait_for_loader/2` from API (deprecated in 1.10.0 - see MIGRATION.md) - ?? `locus:wait_for_loaders/2` from API (deprecated in 1.10.0 - see MIGRATION.md) - ?? `locus:get_version/1` from API (deprecated in 1.4.0 - see MIGRATION.md) - ?? `locus:analyze/1` from API (`locus:check/1` now fulfils this role - see MIGRATION.md) - deprecated loader options `pre_readiness_update_period` and `post_readiness_update_period` (see MIGRATION.md) - warnings on the use of discontinued GeoLite2 HTTP URLs * Migration guide: https://github.com/g-andrade/locus/blob/2.0.0/MIGRATION.md * Hex package: https://hex.pm/packages/locus/2.0.0 * Documentation: https://hexdocs.pm/locus/2.0.0/ * Source code (GitHub): https://github.com/g-andrade/locus/tree/2.0.0 * Source code (GitLab): https://gitlab.com/g-andrade/locus/tree/2.0.0 On Thu, 21 May 2020 at 02:48, Guilherme Andrade wrote: > Hi list, > > Locus 1.12.0, a MaxMind DB reader, was released today. > > Added: > - support for OTP 23 > > Changed: > - checksum verification algorithm of MaxMind downloads from MD5 to SHA-256 > >> > > * Hex package: https://hex.pm/packages/locus/1.12.0 > * Documentation: https://hexdocs.pm/locus/1.12.0/ > * Source code (GitHub): https://github.com/g-andrade/locus/tree/1.12.0 > * Source code (GitLab): https://gitlab.com/g-andrade/locus/tree/1.12.0 > > -- > Guilherme > -------------- next part -------------- An HTML attachment was scrubbed... URL: From g@REDACTED Mon Aug 30 02:45:22 2021 From: g@REDACTED (Guilherme Andrade) Date: Mon, 30 Aug 2021 01:45:22 +0100 Subject: [ANN] locus: Geolocation and ASN lookup of IP addresses In-Reply-To: References: Message-ID: On Mon, 30 Aug 2021 at 01:43, Guilherme Andrade wrote: > Hello list, > > Locus 2.0.0, a MaxMind DB reader, was released tonight. > > Added: > - support for retrieving databases using consumer-defined fetchers > - support for decoding IEEE-754 infinities in MMDB data > - `locus:check/1` to API (which replaces `locus:analyze/1` and can be up > to 3200% faster) > - details to MMDB unpacking errors > - linting checks with `rebar3_lint` > - dead code checks with `rebar3_hank` > > Changed: > - ?? return type of `locus:lookup/2` (see MIGRATION.md) > - database loader to use `persistent_term` instead of ETS > - MMDB decoder to perform stricter metadata validations > - MMDB decoder to not crash upon maps containing duplicate keys > - databases downloaded through HTTP(S) without a `last-modified` response > header to no longer be cached > - imported version of `tls_certificate_check` to '~> 1.7' > - single CT suite covering both filesystem and HTTP sources into one for > each > - test coverage for the better > > Removed: > - ?? `locus:wait_for_loader/1` from API (deprecated in 1.10.0 - see > MIGRATION.md) > - ?? `locus:wait_for_loader/2` from API (deprecated in 1.10.0 - see > MIGRATION.md) > - ?? `locus:wait_for_loaders/2` from API (deprecated in 1.10.0 - see > MIGRATION.md) > - ?? `locus:get_version/1` from API (deprecated in 1.4.0 - see > MIGRATION.md) > - ?? `locus:analyze/1` from API (`locus:check/1` now fulfils this role - > see MIGRATION.md) > - deprecated loader options `pre_readiness_update_period` and > `post_readiness_update_period` (see MIGRATION.md) > - warnings on the use of discontinued GeoLite2 HTTP URLs > > > * Migration guide: > https://github.com/g-andrade/locus/blob/2.0.0/MIGRATION.md > * Hex package: https://hex.pm/packages/locus/2.0.0 > * Documentation: https://hexdocs.pm/locus/2.0.0/ > * Source code (GitHub): https://github.com/g-andrade/locus/tree/2.0.0 > * Source code (GitLab): https://gitlab.com/g-andrade/locus/tree/2.0.0 > Mmmh, sorry the the broken links. Here they are: * Migration guide: https://github.com/g-andrade/locus/blob/2.0.0/MIGRATION.md * Hex package: https://hex.pm/packages/locus/2.0.0 * Documentation: https://hexdocs.pm/locus/2.0.0/ * Source code (GitHub): https://github.com/g-andrade/locus/tree/2.0.0 * Source code (GitLab): https://gitlab.com/g-andrade/locus/tree/2.0.0 > > > On Thu, 21 May 2020 at 02:48, Guilherme Andrade wrote: > >> Hi list, >> >> Locus 1.12.0, a MaxMind DB reader, was released today. >> >> Added: >> - support for OTP 23 >> >> Changed: >> - checksum verification algorithm of MaxMind downloads from MD5 to SHA-256 >> >>> >> >> * Hex package: https://hex.pm/packages/locus/1.12.0 >> * Documentation: https://hexdocs.pm/locus/1.12.0/ >> * Source code (GitHub): https://github.com/g-andrade/locus/tree/1.12.0 >> * Source code (GitLab): https://gitlab.com/g-andrade/locus/tree/1.12.0 >> >> -- >> Guilherme >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From max.lapshin@REDACTED Mon Aug 30 07:15:10 2021 From: max.lapshin@REDACTED (Max Lapshin) Date: Mon, 30 Aug 2021 08:15:10 +0300 Subject: [ANN] locus: Geolocation and ASN lookup of IP addresses In-Reply-To: References: Message-ID: Does it still tries to download database itself? From vances@REDACTED Mon Aug 30 16:22:13 2021 From: vances@REDACTED (Vance Shipley) Date: Mon, 30 Aug 2021 22:22:13 +0800 Subject: Local Process Registered Name as Term In-Reply-To: References: Message-ID: What advice can I get on a process registry solution for local (only) lookup using term() rather than atom()? The obvious candidates are erlang:register/2 for atoms and global:register_name/2 for other terms: erlang:register(Name :: atom()), PidOrPort) -> global:register_name(Name :: term(), Pid) -> Which is fine however when it will only be used locally global is a heavyweight solution. Should I roll my own using ets? A process? Other? -- -Vance -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank.muller.erl@REDACTED Mon Aug 30 16:31:21 2021 From: frank.muller.erl@REDACTED (Frank Muller) Date: Mon, 30 Aug 2021 16:31:21 +0200 Subject: Local Process Registered Name as Term In-Reply-To: References: Message-ID: Hi Vance Checkout gproc or syn. /F. What advice can I get on a process registry solution for local (only) > lookup using term() rather than atom()? > > The obvious candidates are erlang:register/2 for atoms and > global:register_name/2 for other terms: > > erlang:register(Name :: atom()), PidOrPort) -> > global:register_name(Name :: term(), Pid) -> > > Which is fine however when it will only be used locally global is a > heavyweight solution. > > Should I roll my own using ets? A process? Other? > > -- > -Vance > -------------- next part -------------- An HTML attachment was scrubbed... URL: From g@REDACTED Mon Aug 30 17:24:42 2021 From: g@REDACTED (Guilherme Andrade) Date: Mon, 30 Aug 2021 16:24:42 +0100 Subject: [ANN] locus: Geolocation and ASN lookup of IP addresses In-Reply-To: References: Message-ID: Hello Max, Yes it does - although now you have a choice, as there's a new API[*] for unpacking the database from a binary and using the result as see fit, which allows for new use cases. [*]: https://hexdocs.pm/locus/2.0.0/locus_mmdb.html#unpack_database-1 On Mon, 30 Aug 2021 at 06:15, Max Lapshin wrote: > Does it still tries to download database itself? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From max.lapshin@REDACTED Mon Aug 30 17:31:32 2021 From: max.lapshin@REDACTED (Max Lapshin) Date: Mon, 30 Aug 2021 18:31:32 +0300 Subject: [ANN] locus: Geolocation and ASN lookup of IP addresses In-Reply-To: References: Message-ID: This is a well known problem with such libraries. Without proper updating data it is not 100% useable as it can be, but library that goes itself somewhere into the internet is not very easy to integrate. Especially when we do not have standard http client in erlang (and in elixir). On Mon, Aug 30, 2021 at 6:24 PM Guilherme Andrade wrote: > > Hello Max, > > Yes it does - although now you have a choice, as there's a new API[*] for unpacking the database from a binary and using the result as see fit, which allows for new use cases. > > [*]: https://hexdocs.pm/locus/2.0.0/locus_mmdb.html#unpack_database-1 > > On Mon, 30 Aug 2021 at 06:15, Max Lapshin wrote: >> >> Does it still tries to download database itself? From max.lapshin@REDACTED Mon Aug 30 17:32:44 2021 From: max.lapshin@REDACTED (Max Lapshin) Date: Mon, 30 Aug 2021 18:32:44 +0300 Subject: Local Process Registered Name as Term In-Reply-To: References: Message-ID: I've created our gen_tracker that is used for this during many years. https://github.com/erlyvideo/gen_tracker On Mon, Aug 30, 2021 at 5:31 PM Frank Muller wrote: > > Hi Vance > > Checkout gproc or syn. > > /F. > >> What advice can I get on a process registry solution for local (only) lookup using term() rather than atom()? >> >> The obvious candidates are erlang:register/2 for atoms and global:register_name/2 for other terms: >> >> erlang:register(Name :: atom()), PidOrPort) -> >> global:register_name(Name :: term(), Pid) -> >> >> Which is fine however when it will only be used locally global is a heavyweight solution. >> >> Should I roll my own using ets? A process? Other? >> >> -- >> -Vance From g@REDACTED Mon Aug 30 19:22:15 2021 From: g@REDACTED (Guilherme Andrade) Date: Mon, 30 Aug 2021 18:22:15 +0100 Subject: [ANN] locus: Geolocation and ASN lookup of IP addresses In-Reply-To: References: Message-ID: I understand, and have faced such problems myself - there's an inherent reliability issue. But it can be worked around in multiple ways: - by having your own HTTP(S) mirror (which is possible since 1.0.0) - by loading the database from the file system (which is possible since 1.3.0, from March 2018) - and starting now, by fetching the data however you see fit, through callbacks As for the issue of picking a HTTP client in particular, I've so far avoided it by sticking with the stdlib's httpc. But CA validation is still required for HTTPS (or rather, **strongly** recommended), and so there's a dependency there (and one that requires regular updates.) On Mon, 30 Aug 2021 at 16:31, Max Lapshin wrote: > This is a well known problem with such libraries. > > Without proper updating data it is not 100% useable as it can be, but > library that goes itself somewhere into the internet is not very easy > to integrate. > > Especially when we do not have standard http client in erlang (and in > elixir). > > On Mon, Aug 30, 2021 at 6:24 PM Guilherme Andrade wrote: > > > > Hello Max, > > > > Yes it does - although now you have a choice, as there's a new API[*] > for unpacking the database from a binary and using the result as see fit, > which allows for new use cases. > > > > [*]: https://hexdocs.pm/locus/2.0.0/locus_mmdb.html#unpack_database-1 > > > > On Mon, 30 Aug 2021 at 06:15, Max Lapshin wrote: > >> > >> Does it still tries to download database itself? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From g@REDACTED Tue Aug 31 00:18:09 2021 From: g@REDACTED (Guilherme Andrade) Date: Mon, 30 Aug 2021 23:18:09 +0100 Subject: [ANN] locus: Geolocation and ASN lookup of IP addresses In-Reply-To: References: Message-ID: Well list, Locus 2.1.0 is out! (/that didn't take long/) Highlights: - a couple of bugfixes in locus:check/1 - a couple of new API functions which were missing being made public - CI on Windows Hopefully stable now. On Mon, 30 Aug 2021 at 01:43, Guilherme Andrade wrote: > Hello list, > > Locus 2.0.0, a MaxMind DB reader, was released tonight. > > Added: > - support for retrieving databases using consumer-defined fetchers > - support for decoding IEEE-754 infinities in MMDB data > - `locus:check/1` to API (which replaces `locus:analyze/1` and can be up > to 3200% faster) > - details to MMDB unpacking errors > - linting checks with `rebar3_lint` > - dead code checks with `rebar3_hank` > > Changed: > - ?? return type of `locus:lookup/2` (see MIGRATION.md) > - database loader to use `persistent_term` instead of ETS > - MMDB decoder to perform stricter metadata validations > - MMDB decoder to not crash upon maps containing duplicate keys > - databases downloaded through HTTP(S) without a `last-modified` response > header to no longer be cached > - imported version of `tls_certificate_check` to '~> 1.7' > - single CT suite covering both filesystem and HTTP sources into one for > each > - test coverage for the better > > Removed: > - ?? `locus:wait_for_loader/1` from API (deprecated in 1.10.0 - see > MIGRATION.md) > - ?? `locus:wait_for_loader/2` from API (deprecated in 1.10.0 - see > MIGRATION.md) > - ?? `locus:wait_for_loaders/2` from API (deprecated in 1.10.0 - see > MIGRATION.md) > - ?? `locus:get_version/1` from API (deprecated in 1.4.0 - see > MIGRATION.md) > - ?? `locus:analyze/1` from API (`locus:check/1` now fulfils this role - > see MIGRATION.md) > - deprecated loader options `pre_readiness_update_period` and > `post_readiness_update_period` (see MIGRATION.md) > - warnings on the use of discontinued GeoLite2 HTTP URLs > > > * Migration guide: > https://github.com/g-andrade/locus/blob/2.0.0/MIGRATION.md > * Hex package: https://hex.pm/packages/locus/2.0.0 > * Documentation: https://hexdocs.pm/locus/2.0.0/ > * Source code (GitHub): https://github.com/g-andrade/locus/tree/2.0.0 > * Source code (GitLab): https://gitlab.com/g-andrade/locus/tree/2.0.0 > > > On Thu, 21 May 2020 at 02:48, Guilherme Andrade wrote: > >> Hi list, >> >> Locus 1.12.0, a MaxMind DB reader, was released today. >> >> Added: >> - support for OTP 23 >> >> Changed: >> - checksum verification algorithm of MaxMind downloads from MD5 to SHA-256 >> >>> >> >> * Hex package: https://hex.pm/packages/locus/1.12.0 >> * Documentation: https://hexdocs.pm/locus/1.12.0/ >> * Source code (GitHub): https://github.com/g-andrade/locus/tree/1.12.0 >> * Source code (GitLab): https://gitlab.com/g-andrade/locus/tree/1.12.0 >> >> -- >> Guilherme >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ifl21.publicity@REDACTED Mon Aug 30 21:32:15 2021 From: ifl21.publicity@REDACTED (Pieter Koopman) Date: Mon, 30 Aug 2021 12:32:15 -0700 Subject: IFL'21 final call for participation Message-ID: ================================================================================ IFL 2021 33rd Symposium on Implementation and Application of Functional Languages venue: online 1 - 3 September 2021 https://ifl21.cs.ru.nl *Registration* *Registration is **free of charge, but required for participation!* We will mail the zoom link only to registered participants. Use the below link to register for IFL 2021: https://docs.google.com/forms/d/e/1FAIpQLSdMFjo-GumKjk4i7szs7n4DhWqKt96t8ofIqshfQFrf4jnvsA/viewform?usp=sf_link *Program* The program is now available at https://ifl21.cs.ru.nl/Program . *Scope* The goal of the IFL symposia is to bring together researchers actively engaged in the implementation and application of functional and function-based programming languages. IFL 2021 will be a venue for researchers to present and discuss new ideas and concepts, work in progress, and publication-ripe results related to the implementation and application of functional languages and function-based programming. *Organisation* IFL 2021 Chairs: Pieter Koopman and Peter Achten, Radboud University, The Netherlands IFL Publicity chair: Pieter Koopman, Radboud University, The Netherlands *PC* Peter Achten (co-chair) - Radboud University, Netherlands Thomas van Binsbergen - University of Amsterdam, Netherlands Edwin Brady - University of St. Andrews, Scotland Laura Castro - University of A Coru?a, Spain Youyou Cong - Tokyo Institute of Technology, Japan Olaf Chitil - University of Kent, England Andy Gill - University of Kansas, USA Clemens Grelck - University of Amsterdam, Netherlands John Hughes - Chalmers University, Sweden Pieter Koopman (co-chair) - Radboud University, Netherlands Cynthia Kop - Radboud University, Netherlands Jay McCarthey - University of Massachussetts Lowell, USA Neil Mitchell - Facebook, England Jan De Muijnck-Hughes - Glasgow University, Scotland Keiko Nakata - SAP Innovation Center Potsdam, Germany Jurri?n Stutterheim - Standard Chartered, Singapore Simon Thompson - University of Kent, England Melinda T?th - E?tvos Lor?nd University, Hungary Phil Trinder - Glasgow University, Scotland Meng Wang - University of Bristol, England Vikt?ria Zs?k - E?tvos Lor?nd University, Hungary [image: beacon] -------------- next part -------------- An HTML attachment was scrubbed... URL: From serge@REDACTED Tue Aug 31 21:13:51 2021 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 31 Aug 2021 15:13:51 -0400 Subject: [ANN] etran: added support of default function arguments Message-ID: A new version of etran parse transforms has been released. https://github.com/saleyn/etran In this version a "defarg" parse transform is added to support default function arguments. Example: test(A / 10, B / 20) -> A + B. The code above is transformed to: test() -> test(10); test(A) -> test(A, 20); test(A,B) -> A+B. More examples taken from unit tests: defarg_test() -> ?assertEqual(3, a()), ?assertEqual(9, a(7)), ?assertEqual(10, a(6,4)), ?assertEqual(7.0, c()), ?assertEqual(9, d()), ?assertEqual(5, d(abc, [1,2])), ok. a(A / 1, B / 2) -> A+B. c(A / (10*2-15), B / (64 / 32)) -> A + B. d(A / undefined, B / []) -> length(atom_to_list(A)) + length(B). Regards, Serge -------------- next part -------------- An HTML attachment was scrubbed... URL: