1. 3

    pip install psycopg[pool]

    yesss! thank you!

    1. 2

      Do square brackets mean something special in the context of pip? I have used pip a bit bit never seen them before in the package name.

      1. 6

        Python packaging tools have long supported the idea of declaring optional “extras” that can be installed with the main package. The bracket syntax is used to select them, and will trigger installation of additional dependencies to support the requested optional functionality.

        1. 3

          there is a dictionary of optional dependencies in the package’s setup.py file. This name inside the brackets is a key of that dictionary.

      1. 6

        PostgreSQL 14 introduces the ability to “bin”, or align, timestamps to a particular interval using the date_bin function

        Exciting news for financial aggregations.

        1. 2

          Always good to see someone diving into the interpreter internals, but man I find supporting -‘ incomplete ternary expression to be a weirdly uncomfortable motivation for doing so.

          1. 3

            It is a complete expression, else defaults to None and you can’t return from your weirdly comfortable ternary expression whereas you can conditionally return from a function with postfix if which btw is a one-liner.

            1. 1

              It is a complete expression

              Didn’t say it wasn’t; I said it was an incomplete ternary expression, which is definitionally true.

              else defaults to None

              Understood, but not obviously a compelling syntactical feature and, if you ever decide to take up typing discipline, an antipattern in the making.

              and you can’t return from your weirdly comfortable ternary expression whereas you can conditionally return from a function with postfix if which btw is a one-liner

              Also not exactly a compelling feature, and returning from within an expression is ambiguous in a statement based language:

               value = return 42 if True
              

              Is that valid syntax? Is value dead code? Or can it only ever be None if reachable?

              Besides, you can already conditionally return in one line, so not sure that ability adds anything:

              if True: return 42
              

              I’m not some huge fan of Python’s ternary conditional, having picked up TCL’s terser version first, but shoe-horning TCL style syntax would also be an odd motivator for forking my own personal Python, with all the distribution problems that brings.

              1. 1

                Return with a bottle of wine if you can. I want wine conditionally and you want my statement to be as readable as possible. So it is obviously not an anti-pattern.

                value = return 42 if True
                
                # Is that valid syntax? Is value dead code? Or can it only ever be None if reachable?
                

                It would be invalid syntax. rhs can’t be a void value. Are we just making up uses where syntax might be confusing or harder to read? Is that the point?

                value = if True: return 42  
                

                This would probably throw the same error if if expressions could be used as rhs. Unfortunately they cannot be and it is an error. Another missing feature. The syntax is miserable, but yes, it is a one-liner.

                1. 1

                  Return with a bottle of wine if you can. I want wine conditionally and you want my statement to be as readable as possible. So it is obviously not an anti-pattern.

                  The statement:

                  return bottle if wine else None
                  

                  … is arguably more readable than:

                   return bottle if wine
                  

                  … if only because what is returned is explicit in all cases. Both are an antipattern when you’re being disciplined on types, because you’ve got one expression that evaluates to more than one possible type.

                  Are we just making up uses where syntax might be confusing or harder to read? Is that the point?

                  No attempt at straw manning, I’m actually uncertain of what valid syntax is for return in this two-thirds-of-ternary form. That uncertainty comes from its inherent instability, does:

                  return bottle if wine
                  print(“foo”)
                  

                  Return either bottle or None, terminating the function and making the print unreachable, or does control flow continue past that line of wine is False?

                  return bottle if wine else None
                  print(“foo”)
                  

                  Notice how there’s no question here that the print is unreachable.

                  Unfortunately they cannot be and it is an error.

                  The ternary if form — the only form of if expression in Python — can be used as the RHS of a return. The language just requires that such an expression must unambiguously evaluate to either the LHS or the RHS of the “if predicate” portion. Trying to return an if statement is nonsensical and should error.

                  Another missing feature. The syntax is miserable, but yes, it is a one-liner.

                  I see no missing feature. All I see is a bit of syntactic sugar that seems to have no obvious positives — without more clearly understanding the valid uses of return-if it certainly looks like it’s just the ternary if with “else None” elided — but which very clearly conflicts with two of the maxims of the Zen of Python (one obvious way to do things and explicit is better than implicit). As for the syntax being “miserable”… well that’s how I feel about Ruby, generally, so not sure we’ll come to any meaningful conclusions on that particular unprovable value judgement.

                  1. 1

                    I think the confusion lies where you missed the second half of the post where postfix if makes the return conditional. Else None makes it completely different. It will return None if condition is not met. This is not what it does. Yes, “finding syntax useful” is subjective, but it exists, and it is used, so it is useful. And it will lose its use when people stop using it. That’s the pragmatic solution to your philosophical dilemma. And you can have Optional[int] as the return type in python, so I don’t understand your protests of having anti-patterns and type inconsistencies. That’s where python does better I think. And that’s why I use it instead of ruby.

                    1. 1

                      I think the confusion lies where you missed the second half of the post where postfix if makes the return conditional. Else None makes it completely different. It will return None if condition is not met. This is not what it does.

                      No, I didn’t miss the second half of the post, what I’m saying is that the Ruby-style syntax is inherently ambiguous, and that using the nil case to bypass return is semantically weird, logically inconsistent, and confusing to learners, all in one go.

                      In Python the semantics of;

                      var = EXPR
                      return var
                      raise RuntimeError()
                      

                      … are unambiguous; we always return whatever EXPR evaluates to, and in all cases control flow ceases and any code below the return statement is unreachable. I can glance at this and know that error is never raised.

                      More importantly those first lines contracted into one one always has precisely the same behavior (modulo incrementing and decrementing a reference counter):

                      return EXPR
                      raise RuntimeError()
                      

                      But in Ruby-style syntax that’s not the case:

                      var = EXPR
                      return var
                      raise RuntimeError()
                      

                      … can never throw that error, while:

                      return EXPR
                      raise RuntimeError()
                      

                      might do so, because EXPR may include a conditional.

                      Besides, there already exists an obvious way to do this motivating example:

                      def foo(test):
                           a = 1
                           return a if test
                           a += 1
                           return a
                      

                      … without considering early return at all:

                      def foo(test):
                           a = 1
                           if test:
                               a += 1
                           return a
                      

                      Yes, “finding syntax useful” is subjective, but it exists, and it is used, so it is useful. And it will lose its use when people stop using it.

                      Ahh, but it doesn’t exist in Python, and the present debate is over whether or not it makes sense to go to the trouble of adding an ambiguous and inconsistent feature to the language when, again, the addition essentially duplicates and mildly bikesheds functionality that has already been provided in an unambiguous and consistent way. Personally I’m all for this useful thing losing its use, but I’m sure it shouldn’t be added to the language in a misguided attempt to increase its use.

                      That’s the pragmatic solution to your philosophical dilemma.

                      I haven’t got a dilemma, and arguably the most pragmatic solution is to use the idioms of a language as you find them, rather than trying to shoehorn in idioms lifted from other languages, especially when those foreign idioms already have native solutions that are perfectly workable.

                      1. 1

                        I think this is a pointless argument for inconsistency and shoehorning full of your personal preferences using counterexamples since you can do it for any language where the same keyword is used for two different idioms.

                        1. 1

                          Think what you’d like, but if you’re not ready to address concerns such those as I’ve raised you’ll never get your personal preference for this new idiom adopted into Python. Of course you’re welcome to incorporate it into your own personal Mython, though I’m not sure the distribution pain is worth it. But hey, you choose what hill to die on.

                          1. 1

                            You think I’d go to lengths to get my idea implemented and that your “arguments” provide some sort of basis for validity? Illusions of grandeur? It’s inconsistent because I don’t expect it. It’s an anti-pattern because I don’t know what Optional means. Languages don’t need new features because you can use existing syntax. Clicking reply on lobste.rs or any forum is not the kind of actual I would take if I wanted to get this implemented. I would go implement it, come up with a couple of actual useful real life examples, write a PEP and send a diff.

                            1. 1

                              I would go implement it, come up with a couple of actual useful real life examples, write a PEP and send a diff.

                              Please do. Then watch it be rejected for all the reasons listed above.

                              The phrase is “delusions of grandeur”, BTW.

                              1. 1

                                Great, thanks for your time.

          1. 17

            Pattern matching has been available in functional programming languages for decades now, it was introduced in the 70s. (Logic programming languages expose even more expressive forms, at higher runtime cost.) It obviously improves readability of code manipulating symbolic expressions/trees, and there is a lot of code like this. I find it surprising that in the 2020s there are still people wondering whether “the feature provides enough value to justify its complexity”.

            (The fact that Python did without for so long was rather a sign of closed-mindedness of its designer subgroup. The same applies, in my opinion, to languages (including Python, Go, etc.) that still don’t have proper support for disjoint union types / variants / sums / sealed case classes.)

            1. 45

              Pretty much every feature that has ever been added to every language ever is useful in some way. You can leave a comment like this on almost any feature that a language may not want to implement for one reason or the other.

              1. 14

                I think it makes more sense in statically typed languages, especially functional ones. That said, languages make different choices. For me, Python has always been about simplicity and readability, and as I’ve tried to show in the article, at least in Python, structural pattern matching is only useful in a relatively few cases. But it’s also a question of taste: I really value the simplicity of the Go language (and C before it), and don’t mind a little bit of verbosity if it makes things clearer and simpler. I did some Scala for a while, and I can see how people like the “power” of it, but the learning curve of its type system was very steep, and there were so many different ways to do things (not to mention the compiler was very slow, partly because of the very complex type system).

                1. 22

                  For the record, pattern-matching was developed mostly in dynamically-typed languages before being adopted in statically-typed languages, and it works just as well in a dynamically-typed world. (In the ML-family world, sum types and pattern-matching were introduced by Hope, an experimental dynamically-typed language; in the logic world, they are basic constructs of Prolog, which is also dynamically-typed – although some more-typed dialects exist.)

                  as I’ve tried to show in the article, at least in Python, structural pattern matching is only useful in a relatively few cases

                  Out of the 4 cases you describe in the tutorial, I believe your description of two of them is overly advantageous to if..elif:

                  • In the match event.get() case, the example you show is a variation of the original example (the longer of the three such examples in the tutorial), and the change you made makes it easier to write an equivalent if..elif version, because you integrated a case (from another version) that ignores all other Click() events. Without this case (as in the original tutorial example), rewriting with if..elif is harder, you need to duplicate the failure case.
                  • In the eval_expr example, you consider the two versions as readable, but the pattern-version is much easier to maintain. Consider, for example, supporting operations with 4 or 5 parameters, or adding an extra parameter to an existing operator; it’s an easy change with the pattern-matching version, and requires boilerplate-y, non-local transformations with if..elif. These may be uncommon needs for standard mathematical operations, but they are very common when working with other domain-specific languages.
                  1. 1

                    the change you made makes it easier to write an equivalent if..elif version

                    Sorry if it appeared that way – that was certainly not my intention. I’m not quite sure what you mean, though. The first/original event example in the tutorial handles all click events with no filtering using the same code path, so it’s even simpler to convert. I added the Button.LEFT filtering from a subsequent example to give it a bit more interest so it wasn’t quite so simple. I might be missing something, though.

                    In the eval_expr example, you consider the two versions as readable, but the pattern-version is much easier to maintain. Consider, for example, supporting operations with 4 or 5 parameters, or adding an extra parameter to an existing operator;

                    I think those examples are very hypothetical – as you indicate, binary and unary operators aren’t suddenly going to support 4 or 5 parameters. A new operation might, but that’s okay. The only line that’s slightly repetitive is the “attribute unpacking”: w, x, y, z = expr.w, expr.x, expr.y, expr.z.

                    These may be uncommon needs for standard mathematical operations, but they are very common when working with other domain-specific languages.

                    You’re right, and that’s part of my point. Python isn’t used for implementing compilers or interpreters all that often. That’s where I’m coming from when I ask, “does the feature provide enough value to justify the complexity?” If 90% of Python developers will only rarely use this complex feature, does it make sense to add it to the language?

                    1. 3

                      that was certainly not my intention.

                      To be clear, I’m not suggesting that the change was intentional or sneaky, I’m just pointing out that the translation would be more subtle.

                      The first/original event example does not ignore “all other Click events” (there is no Click() case), and therefore an accurate if..elif translation would have to do things differently if there is no position field or if it’s not a pair, namely it would have to fall back to the ValueError case.

                      You’re right, and that’s part of my point. Python isn’t used for implementing compilers or interpreters all that often.

                      You don’t need to implement a compiler for C or Java, or anything people recognize as a programming language (or HTML or CSS, etc.), to be dealing with a domain-specific languages. Many problem domains contain pieces of data that are effectively expressions in some DSL, and recognizing this can very helpful to write programs in those domains – if the language supports the right features to make this convenient. For example:

                      • to start with the obvious, many programs start by interpreting some configuration file to influence their behavior; many programs have simple needs well-served by linear formats, but many programs (eg. cron jobs, etc.) require more elaborate configurations that are DSL-like. Even if the configuration is written in some standard format (INI, Yaml, etc.) – so parsing can be delegated to a library – the programmer will still write code to interpret or analyze the configuration data.
                      • more gnerally, “structured data formats” are often DSL-shaped; ingesting structured data is something we do super-often in programs
                      • programs that offer a “query” capability typically provide a small language to express those queries
                      • events in an event loop typically form a small language
                  2. 14

                    I think it makes more sense in statically typed languages, especially functional ones.

                    In addition to the earlier ones gasche mentioned (it’s important to remember this history), it’s used to pervasively in Erlang, and later Elixir. Clojure has core.match, Racket has match, as does Guile. It’s now in Ruby as well!

                    1. 3

                      Thanks! I didn’t know that. I have used pattern matching in statically typed language (mostly Scala), and had seen it in the likes of Haskell and OCaml, so I’d incorrectly assumed it was mainly a statically-typed language thing.

                      1. 1

                        It is an important feature of OCaml.

                        1. 3

                          I am aware - was focusing on dynamically typed languages.

                      2. 7

                        For me, it is the combination of algebraic data types + pattern matching + compile time exhaustiveness checking that is the real game changer. With just 1 out of 3, pattern matching in Python is much less compelling.

                        1. 1

                          I agree. I wonder if they plan to add exhaustiveness checking to mypy. The way the PEP is so no hold barred makes it seem like the goal was featurefulness and not an attempt to support exhaustiveness checking.

                          1. 2

                            I wonder if they plan to add exhaustiveness checking to mypy.

                            I don’t think that’s possible in the general case. If I understand the PEP correctly, __match_args__ may be a @property getter method, which could read the contents of a file, or perform a network request, etc.

                      3. 11

                        I find it surprising that in the 2020s there are still people wondering whether “the feature provides enough value to justify its complexity”.

                        I find it surprising that people find this surprising.

                        Adding features like pattern matching isn’t trivial, and adding it too hastily can backfire in the long term; especially for an established language like Python. As such I would prefer a language take their time, rather than slapping things on because somebody on the internet said it was a good idea.

                        1. 3

                          That’s always been the Scheme philosophy:

                          Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.

                          And indeed, this pays off: in the Scheme world, there’s been a match package floating around for a long time, implemented simply as a macro. No changes to the core language needed.

                          1. 4

                            No changes to the core language needed.

                            I’m sure you recognize that this situation does not translate to other languages like in this case Python. Implementing it as a macro is just not feasible. And even in Scheme the usage of match macros is rather low. This can be because it is not that useful, but also might be because of the hurdle of adding dependencies is not worth the payoff. Once a feature is integrated in a language, its usage “costs” nothing, thus the value proposition when writing code can be quite different.

                            1. 7

                              This is rather unrelated to the overall discussion, but as a user of the match macros in Scheme, I must say that I find the lack of integration into the base forms slightly annoying. You cannot pattern-match on a let or lambda, you have to use match-let and match-lambda, define/match (the latter only in Racket I think), etc. This makes reaching for pattern-matching feel heavier, and it may be a partial cause to their comparatively lower usage. ML-family languages generalize all binding positions to accept patterns, which is very nice to decompose records for example (or other single-case data structures). I wish Scheme dialects would embrace this generalization, but they haven’t for now – at least not Racket or Clojure.

                              1. 2

                                In the case of Clojure while it doesn’t have pattern matching built-in, it does have quite comprehensive destructuring forms (like nested matching in maps, with rather elaborate mechanisms) that works in all binding positions.

                                1. 2

                                  Nice! I suppose (from your post above) that pattern-matching is somehow “integrated” in the Clojure implementation, rather than just being part of the base macro layer that all users see.

                                  1. 2

                                    I think the case is that Clojure core special forms support it (I suppose the implementation itself is here and called “binding-forms”, which is then used by let, fn and loop which user defined macros often end up expanding to). Thus it is somewhat under the base layer that people use.

                                    But bear in mind this is destructuring, in a more general manner than what Python 2.x already supported, not pattern matching. It also tends to get messy with deep destructuring, but the same can be said of deep pattern matches through multiple layers of constructors.

                        2. 8

                          I agree about pattern matching and Python in general. It’s depressing how many features have died in python-ideas because it takes more than a few seconds for an established programmer to grok them. Function composition comes to mind.

                          But I think Python might be too complicated for pattern matching. The mechanism they’ve settled on is pretty gnarly. I wrote a thing for pattern matching regexps to see how it’d turn out (admittedly against an early version of the PEP; I haven’t checked it against the current state) and I think the results speak for themselves.

                          1. 6

                            But I think Python might be too complicated for pattern matching. The mechanism they’ve settled on is pretty gnarly.

                            I mostly agree. I generally like pattern matching and have been excited about this feature, but am still feeling out exactly when I’ll use it and how it lines up with my intuition.

                            The part that does feel very Pythonic is that destructuring/unpacking is already pretty pervasive in Python. Not only for basic assignments, but also integrated into control flow constructs. For example, it’s idiomatic to do something like:

                            for key, val in some_dictionary.items():
                                # ...
                            

                            Rather than:

                            for item in some_dictionary.items():
                                key, val = item
                                # ...
                            

                            Or something even worse, like explicit item[0] and item[1]. So the lack of a conditional-with-destructuring, the way we already have foreach-with-destructuring, did seem like a real gap to me, making you have to write the moral equivalent of code that looks more like the 2nd case than the 1st. That hole is now filled by pattern matching. But I agree there are pitfalls around how all these features interact.

                          2. 2
                            for i, (k, v) in enumerate(d.items(), 1): pass
                            

                            looks like pattern matching to me

                            1. 2

                              Go aims for simplicity of maintenance and deployment. It doesn’t “still don’t have those features”. The Go authors avoided them on purpose. If you want endless abstractions in Go, embedding Lisp is a possibilty: https://github.com/glycerine/zygomys

                              1. 5

                                Disjoint sums are a basic programming feature (it models data whose shape is “either this or that or that other thing”, which ubiquitous in the wild just like pairs/records/structs). It is not an “endless abstraction”, and it is perfectly compatible with maintenance and deployment. Go is a nice language in some respects, the runtime is excellent, the tooling is impressive, etc etc. But this is no rational excuse for the lack of some basic language features.

                                We are in the 2020s, there is no excuse for lacking support for sum types and/or pattern matching. Those features have been available for 30 years, their implementation is well-understood, they require no specific runtime support, and they are useful in basically all problem domains.

                                I’m not trying to bash a language and attract defensive reactions, but rather to discuss (with concrete examples) the fact that language designer’s mindsets can be influenced by some design cultures more than others, and as a result sometimes the design is held back by a lack of interest for things they are unfamiliar with. Not everyone is fortunate to be working with a deeply knowledgeable and curious language designer, such as Graydon Hoare; we need more such people in our language design teams. The default is for people to keep working on what they know; this sort of closed-ecosystem evolution can lead to beautiful ideas (some bits of Perl 6 for example are very nice!), but it can also hold back.

                                1. 3

                                  But this is no rational excuse for the lack of some basic language features.

                                  Yes there is. Everyone has a favorite feature, and if all of those are implemented, there would easily be feature bloat, long build times and projects with too many dependencies that depend on too many dependencies, like in C++.

                                  In my opinion, the question is not if a language lacks a feature that someone wants or not, but if it’s usable for goals that people wish to achieve, and Go is clearly suitable for many goals.

                              2. 3

                                Ah yes, Python is famously closed-minded and hateful toward useful features. For example, they’d never adopt something like, say, list comprehensions. The language’s leaders are far too closed-minded, and dogmatically unwilling to ever consider superior ideas, to pick up something like that. Same for any sort of ability to work with lazy iterables, or do useful combinatoric work with them. That’s something that definitely will never be adopted into Python due to the closed-mindedness of its leaders. And don’t get me started on basic FP building blocks like map and folds. It’s well known that Guido hates them so much that they’re permanently forbidden from ever being in the language!

                                (the fact that Python is not Lisp was always unforgivable to many people; the fact that it is not Haskell has now apparently overtaken that on the list of irredeemable sins; yet somehow we Python programmers continue to get useful work done and shrug off the sneers and insults of our self-proclaimed betters much as we always have)

                                1. 25

                                  It is well-documented that Guido Van Rossum planned to remove lambda from Python 3. (For the record, I agree that map and filter on lists are much less useful in presence of list comprehensions.) It is also well-documented that recursion is severely limited in Python, making many elegant definitions impractical.

                                  Sure, Python adopted (in 2000 I believe?) list comprehensions from ABC (due to Guido working with the language in the 1980s), and a couple of library-definable iterators. I don’t think this contradicts my claim. New ideas came to the language since (generators, decorators), but it remains notable that the language seems to have resisted incorporating strong ideas from other languages. (More so than, say, Ruby, C#, Kotlin, etc.)

                                  Meta: One aspect of your post that I find unpleasant is the tone. You speak of “sneers and insults”, but it is your post that is highly sarcastic and full of stray exagerations at this or that language community. I’m not interested in escalating in this direction.

                                  1. 7

                                    less useful in presence of list comprehension

                                    I’m certainly biased, but I find Python’s list comprehension an abomination towards readability in comparison to higher-order pipelines or recursion. I’ve not personally coded Python in 8-9 years, but when I see examples, I feel like I need to put my head on upsidedown to understand it.

                                    1. 6

                                      It is also well-documented that recursion is severely limited in Python, making many elegant definitions impractical.

                                      For a subjective definition of “elegant”. But this basically is just “Python is not Lisp” (or more specifically, “Python is not Scheme”). And that’s OK. Not every language has to have Scheme’s approach to programming, and Scheme’s history has shown that maybe it’s a good thing for other languages not to be Scheme, since Scheme has been badly held back by its community’s insistence that tail-recursive implementations of algorithms should be the only implementations of those algorithms.

                                      You speak of “sneers and insults”, but it is your post that is highly sarcastic and full of stray exagerations at this or that language community.

                                      Your original comment started from a place of assuming – and there really is no other way to read it! – that the programming patterns you care about are objectively superior to other patterns, that languages which do not adopt those patterns are inherently inferior, and that the only reason why a language would not adopt them is due to “closed-mindedness”. Nowhere in your comment is there room for the (ironically) open-minded possibility that someone else might look at patterns you personally subjectively love, evaluate them rationally, and come to a different conclusion than you did – rather, you assume that people who disagree with your stance must be doing so because of personal faults on their part.

                                      And, well, like I said we’ve got decades of experience of people looking down their noses at Python and/or its core team + community for not becoming a copy of their preferred languages. Your comment really is just another instance of that.

                                      1. 8

                                        I’m not specifically pointing out the lack of tail-call optimization (TCO) in Python (which I think is unfortunate indeed; the main argument is that call stack matters, but it’s technically fully possible to preserve call stacks on the side with TC-optimizing implementations). Ignoring TCO for a minute, the main problem would be the fact that the CPython interpreter severely limits the call space (iirc it’s 1K calls by default; compare that to the 8Mb default on most Unix systems), making recursion mostly unusable in practice, except for logarithmic-space algorithms (balanced trees, etc.).

                                        Scheme has been badly held back by its community’s insistence that tail-recursive implementations of algorithms should be the only implementations of those algorithms.

                                        I’m not sure what you mean – that does not make any sense to me.

                                        [you assume] that the programming patterns you care about are objectively superior to other patterns [..]

                                        Well, I claimed

                                        [pattern matching] obviously improves readability of code manipulating symbolic expressions/trees

                                        and I stand by this rather modest claim, which I believe is an objective statement. In fact it is supported quite well by the blog post that this comment thread is about. (Pattern-matching combines very well with static typing, and it will be interesting to see what Python typers make of it; but its benefits are already evident in a dynamically-typed context.)

                                        1. 4

                                          and I stand by this rather modest claim, which I believe is an objective statement.

                                          Nit: I don’t think you can have an objective statement of value.

                                          1. 4

                                            Again: your original comment admits of no other interpretation than that you do not believe anyone could rationally look at the feature you like and come to a different conclusion about it. Thus you had to resort to trying to find personal fault in anyone who did.

                                            This does not indicate “closed-mindedness” on the part of others. They may prioritize things differently than you do. They may take different views of complexity and tradeoffs (which are the core of any new language-feature proposal) than you do. Or perhaps they simply do not like the feature as much as you do. But you were unwilling to allow for this — if someone didn’t agree with your stance it must be due to personal fault. You allowed for no other explanation.

                                            That is a problem. And from someone who’s used to seeing that sort of attitude it will get you a dismissive “here we go again”. Which is exactly what you got.

                                        2. 4

                                          This is perhaps more of a feeling, but saying that Rust isn’t adopting features as quickly as Ruby seems a bit off. Static type adoption in the Python community has been quicker. async/await has been painful, but is being attempted. Stuff like generalized unpacking (and this!) is also shipping out!

                                          Maybe it can be faster, but honestly Python probably has one of the lowest “funding amount relative to impact” of the modern languages which makes the whole project not be able to just get things done as quickly IMO.

                                          Python is truly in a funny place, where many people loudly complain about it not adopting enough features, and many other loudly complain about it loudly adopting too many! It’s of course “different people have different opinions” but still funny to see all on the same page.

                                          1. 3

                                            It is well-documented that Guido Van Rossum planned to remove lambda from Python 3

                                            Thank you for sharing that document. I think Guido was right: it’s not pythonic to map, nor to use lambdas in most cases.

                                            Every feature is useful, but some ecosystems work better without certain features. I’m not sure where go’s generics fall on this spectrum, but I’m sure most proposed features for python move it away from it’s core competency, rather than augmenting a strong core.

                                            1. 1

                                              We have previously discussed their tone problem. It comes from their political position within the Python ecosystem and they’re relatively blind to it. Just try to stay cool, I suppose?

                                              1. 6

                                                I really do recommend clicking through to that link, and seeing just what an unbelievably awful thing I said that the user above called out as “emblematic” of the “contempt” I display to Python users. Or the horrific ulterior motive I was found to have further down.

                                                Please, though, before clicking through, shield the eyes of children and anyone else who might be affected by seeing such content.

                                            2. 5

                                              To pick one of my favorite examples, I talked to the author of PEP 498 after a presentation that they gave on f-strings, and asked why they did not add destructuring for f-strings, as well as whether they knew about customizeable template literals in ECMAScript, which trace their lineage through quasiliterals in E all the way back to quasiquotation in formal logic. The author knew of all of this history too, but told me that they were unable to convince CPython’s core developers to adopt any of the more advanced language features because they were not seen as useful.

                                              I think that this perspective is the one which might help you understand. Where you see one new feature in PEP 498, I see three missing subfeatures. Where you see itertools as a successful borrowing of many different ideas from many different languages, I see a failure to embrace the arrays and tacit programming of APL and K, and a lack of pattern-matching and custom operators compared to Haskell and SML.

                                            3. 1

                                              I think the issue is more about pattern matching being a late addition to Python, which means there will be lots of code floating around that isn’t using match expressions. Since it’s not realistic to expect this code to be ported, the old style if … elif will continue to live on. All of this adds up to a larger language surface area, which makes tool support, learning and consistency more difficult.

                                              I’m not really a big fan of this “pile of features” style of language design - if you add something I’d prefer if something got taken away as well. Otherwise you’ll end up with something like Perl 5

                                            1. 1

                                              Why not use template<typename T> std::optional<Result<T>> f(); //?

                                              1. 2

                                                When there are a lot of parameters to pass and there are some defaults, I use dataclasses. You get a field(default_factory=list) syntax and you are able to pass the parameters as a group to other functions as well.

                                                1. 2

                                                  Are databases considered as dependencies? What about web servers, load balancers, reverse proxies, operating systems? It seems like there is a missing line in the graph. I think it should have “Benefit of a dependency” going downwards over time vs “Benefit of rewriting from scratch” going upward over time.

                                                  1. 2

                                                    It sounds as if there’s also a tightness of coupling argument. A web server is a great example here: it’s pretty trivial to swap out Ningx for Apache (or vice versa) without changing any of the rest of your stack. Reverse proxies, by design, are transparent and so this is even more true there. Databases are a lot more interesting because if you’re using some middleware or sticking to standard SQL then you can often swap them out quite easily, but if you’re using a lot of vendor-specific features then this is much more difficult.

                                                    1. 1

                                                      From TFA:

                                                      Few companies will reinvent a database for their project, yet if you’re operating on Google’s scale it can actually make sense.

                                                    1. 1

                                                      IMO forced meetings are harmful. You are pressed to find something useful to talk about in order to avoid making the meeting a loss of time. Turns out having to find useful things, you only end up with sub-par items. And for actual useful items, you end up waiting a day at which point you either forget some of it or are not enthusiastic about it anymore and this is multiplied with the number of participants. So unless the meeting coincides with the issue, it ends up harming more than helping.

                                                      The more useful way of doing things is to complain about your blockers soon after trying your best. It doesn’t matter if it is caused by your lack of skills or competence or just bureaucracy. And declare your tasks as complete as soon as you are ready and comfortable.

                                                      1. 12

                                                        I’m confused by the distinction between Emacs and an IDE. In what way is Emacs not an IDE? It’s more of an integrated environment than any other IDE I have used, IntelliJ included. Hell in Emacs I can read my emails and browse the web.

                                                        1. 19

                                                          That’s a sad terminology confusion: when people say IDE today, they often don’t have the original “integrated” meaning. Rather, they mean “that, which understands the exact semantics of the code and provides semantic-driven code assistance”. PostIntelliJ is the canonical post which captures the essence of this new IDE meaning. As I work on IDEs (in the modern sense), I tried to invent a better term here (code understander) but it doesn’t stick even with me. So I resorted to just re-defining IDE as Intelligent Development Environment.

                                                          While Emacs is indeed probably the most integrated of them all, it doesn’t fare too well on the intelligent bits. There were attempts to add semantic understanding to emacs: CEDET had some grand vision, js2-mode a real parser for JavaScript, but they are nowhere close to the level of semantic support you get in IntelliJ.

                                                          Today, there’s a trend for separating the semantic engine from the editor front-end (LSP), so we might see Emacs as intelligent environment in the future. Qualitatively, I think that Emacs + lsp-mode for a language which has an OK LSP implementation passes as IDE. Quantitatively, today LSP capabilities are inferior to those of IntelliJ.

                                                          1. 2

                                                            Totally agree that our development tooling still has a lot of areas to improve, “intelligent bits” as you call it but also better support in terms of debugging, tracing, and insights into a programs runtime. The existing stepping debugger support in emacs & most other tools are just very basic and haven’t really changed on what existed 25, 30 years ago. A “live development” experience such as with the Smalltalk debugger is still missing in most other tooling (except for Common Lisp / Scheme to some degree).

                                                            In any case, thank you & the rust-analyzer team in particular that Emacs + rust-analyzer is my favorite Rust development environment that is getting better every week!

                                                          2. 2

                                                            I’ve used Vim since the early 2000s. Each tool has a purpose. In Intellij IDEA for example, you can create a kotlin based spring boot project and start debugging or start writinh some test cases and run them to see the coverage. It will underline code where you need to add null checks. It will auto-install dependencies in your pom or gradle files. This is supported out of the box as expected from any IDE. It is a time saver. I install emacs and stare at a blank page. No “create project” menus, no “project options” it just stares with its gray, listless, lifeless terminal screen.

                                                            1. 1

                                                              Good point. “Specialized IDE” would have been more accurate but would have been more verbose

                                                            1. 4

                                                              CSV doesn’t need to go away. Data interchange can still be done in some other human readable/modifiable format and CSV can still be produced in order to support legacy software. The problem with being plaintext/modifiable is: people don’t use linters to check for errors and they don’t count rows and columns before and after modifications. They will do that with any format and you can’t solve for laziness.

                                                              1. 1

                                                                I wonder if this will work on a RPi

                                                                1. 2

                                                                  It runs fine on my Raspberry Pi Zero W.

                                                                1. 31

                                                                  On a technical level it’s implemented very well.

                                                                  It is matching against a list, so unlike a general recognition AI, there’s very little chance of misidentification.

                                                                  The blocklist and matching process is split between client-side and server-side, so it can’t be easily extracted from the phone for nefarious purposes.

                                                                  Apple has spent a considerable effort to cryptographically ensure they know nothing until multiple matches are found. Phone even sends dummy traffic to obscure how many potential matches are there.

                                                                  So as far as scanning for the intended purpose, it’s a careful well thought-out design.

                                                                  I am worried about governments putting pressure on Apple to add more kinds of unwanted images to this list. The list is opaque, and for obvious reasons, it can’t be reviewed.

                                                                  1. 6

                                                                    This is an improvement over their existing policy of giving authoritarian governments access to iCloud keys for their users: https://www.reuters.com/article/us-china-apple-icloud-insight/apple-moves-to-store-icloud-keys-in-china-raising-human-rights-fears-idUSKCN1G8060

                                                                    This technology will allow Apple to expose only content that governments specifically ban rather than having to give them access to everything. We should be celebrating this for both its ability to combat child abuse and that it protects Apple’s customers from over-broad privacy invasion.

                                                                    1. 1

                                                                      This technology will allow Apple to expose only content that governments specifically ban

                                                                      Do governments always make fair and righteous decisions in when deciding what images to ban? I see this situation as disastrous for human rights because you know darn well countries like China will bully Apple into including whatever images they want in that database.

                                                                      1. 1

                                                                        But China including whatever images they want is WAY better for privacy than today when China simply has access to all of Apple’s Chinese users’ data.

                                                                        1. 1

                                                                          That’s not the case, unless you mean to say China bullying Apple into giving them a user’s decryption key? That scenario is possible with or without this system.

                                                                          1. 1

                                                                            This has been the status-quo for the past 3.5 years: https://www.reuters.com/article/us-china-apple-icloud-insight/apple-moves-to-store-icloud-keys-in-china-raising-human-rights-fears-idUSKCN1G8060

                                                                            China demand access to user data so many large American tech companies don’t have a significant presence there. Some American companies that are less committed to privacy comply with the conditions that China places for operating there. It’s a huge market so it’s been a great business move for Apple.

                                                                            Having the ability to scan users’ content in device might be a way to achieve censorship without such indiscriminate access to user data.

                                                                            1. 1

                                                                              The article makes many speculations, but there is nothing concrete regarding the Chinese government having the kind of access you described written in it.

                                                                              Also see this more recent article: https://www.nytimes.com/2021/05/17/technology/apple-china-censorship-data.html

                                                                              Documents reviewed by The Times do not show that the Chinese government has gained access to the data.

                                                                              1. 3

                                                                                Apple user data in China is not controlled by Apple, it’s controlled by GCBD, a company owned by a Chinese regional government. Instead of using standard HSMs they use a hacked up iOS system. Apple’s security chips are vulnerable to local attacks. https://arstechnica.com/information-technology/2020/10/apples-t2-security-chip-has-an-unfixable-flaw/

                                                                                So there’s a government owned company that controls the user data which is encrypted with keys stored in an insecure system. If user data is not being accessed that’s a choice that the Chinese government is making, not a restriction on their access.

                                                                                1. 1

                                                                                  GCBD is the Chinese company that provides apple with datacenter type services. This is not the same as “controls the user data”.

                                                                                  1. 2

                                                                                    From the New York Times article you linked:

                                                                                    U.S. law has long prohibited American companies from turning over data to Chinese law enforcement. But Apple and the Chinese government have made an unusual arrangement to get around American laws.

                                                                                    In China, Apple has ceded legal ownership of its customers’ data to Guizhou-Cloud Big Data, or GCBD, a company owned by the government of Guizhou Province, whose capital is Guiyang. Apple recently required its Chinese customers to accept new iCloud terms and conditions that list GCBD as the service provider and Apple as “an additional party.” Apple told customers the change was to “improve iCloud services in China mainland and comply with Chinese regulations.”

                                                                                    The terms and conditions included a new provision that does not appear in other countries: “Apple and GCBD will have access to all data that you store on this service” and can share that data “between each other under applicable law.”

                                                                                    So to get around US privacy laws and comply with Chinese surveillance laws a Chinese government owned company is the iCloud “service provider” (with Apple listed as an “additional party”) and per the ToS “will have access to all data that you store on this service”.

                                                                                    It was a great business decision. They’re the only major western tech company making a lot of money from the huge Chinese market. I personally wouldn’t want to work there but the people who do are doing very well.

                                                                    2. 2

                                                                      Could such a feature be “pretty easily” fooled to trigger law enforcement to someone as the article implies?

                                                                      Is it plausible to assume that they scan the cached Telegram/Whatsapp/Browser images? If so, how would it behave if someone sends you a set of known infractor images? (an evil chat bot, for example)

                                                                      1. 6

                                                                        Apple says they scan only images in the iCloud library, so images in 3rd party apps and browsers won’t be scanned, unless you save them or screenshot them to your iCloud library. Of course, Apple devices belong to Apple, not you, so Apple could later decide to scan whatever they want.

                                                                        With the current scheme, to cause someone trouble, you’d first have to have multiple banned images to send to them. I hope obtaining actual CSAM is not “pretty easy”.

                                                                        My big worry was that a plaintext blocklist on the phone could be used to generate arbitrary new matching images, but fortunately Apple’s scheme protects against this — the phone doesn’t know if images match. Therefore, you can’t easily make innocent-looking images to trick someone to save them.

                                                                        1. 3

                                                                          Of course, Apple devices belong to Apple, not you, so Apple could later decide to scan whatever they want.

                                                                          Is there a source for this information?

                                                                          1. 3

                                                                            What’s your source for the “multiple banned images” part? Skimmed through Apple’s technical PDF descriptions a bit but didn’t find that part right away.

                                                                            1. 4
                                                                            2. 2

                                                                              Apple says they scan only images in the iCloud library, so images in 3rd party apps and browsers won’t be scanned, unless you save them or screenshot them to your iCloud library.

                                                                              I believe pictures in a lot of messaging apps are automatically uploaded to iCloud. So you could just send someone some pictures over WhatsApp, email, or whatnot. Not 100% sure of this though; I’d have to check. I disabled all the iCloud stuff because it kept nagging.

                                                                              1. 1

                                                                                That or you can generate adversarial images that trigger known hashes. It isn’t using cryptographic hashes, it is using perceptual hashes.

                                                                                1. 1

                                                                                  No, you can’t, because the device doesn’t know if it has got a match.

                                                                                  1. 1

                                                                                    And you think there will be no other way to get ahold of any of the perceptual hashes that are being scanned for?

                                                                                    1. 2

                                                                                      What I’m saying is that you can’t easily abuse Apple’s implementation for this. They’ve anticipated that problem and defended against it.

                                                                                      If you get hold of some hashes or banned images from another source, that’s not Apple’s fault.

                                                                          1. 1

                                                                            I’m so thankful for kotlin, idea community edition and android studio that I can almost forgive the fact that there is no simplified community edition of rubymine which is the only decent ruby IDE out there that works out of the box.

                                                                            1. 2

                                                                              It always upsets me that 1 isn’t prime.

                                                                              1. 7

                                                                                It’s just a convention. It would make a bunch of theorems annoying to state if 1 were prime.

                                                                                1. 3

                                                                                  “1 is a prime” can be the new “tau is superior to pi”.

                                                                                  On a more serious note, I read a bit about this and apparently for a long time 1 wasn’t even considered a number: https://blogs.scientificamerican.com/roots-of-unity/why-isnt-1-a-prime-number/

                                                                                  1. 2

                                                                                    The current ad-hoc definition of a prime is of a natural number with exactly two distinct positive natural divisors. It appeared to be convenient so it was normalized this way about one century ago (but you can still find very old books citing 1 as the first prime number).

                                                                                    1. 2

                                                                                      2 being prime is pretty disappointing as well.

                                                                                      1. 1

                                                                                        1 is only divisible by 1 and itself, but then considering it as prime will destroy “sieve of eratosthenes”

                                                                                      1. 5

                                                                                        This seems fun, and maybe a good tool for build proof of concepts. But I hardly see it as being useful for large projects. Or have I become old and grumpy?

                                                                                        1. 13

                                                                                          As a stranger on the internet, I can be the one to tell you that you are old and grumpy.

                                                                                          Ruby is definitely unusable without syntax highlighting… (Sadists excepted) Java is definitely unusable without code completion… (Sadists excepted) Whatever comes next will probably be unusable without this thing or something like it.

                                                                                          1. 9

                                                                                            I’m confused… Ruby has one of the best syntaxes to read without highlighting. Not as good as forth, but definitely above-average

                                                                                            1. 3

                                                                                              Well, this is the internet. Good luck trying to make sense of every take.

                                                                                              1. 2

                                                                                                I used to think this way. Then I learned Python and now I no longer do.

                                                                                                When I learned Ruby I was coming from Perl, so the Perl syntactic sugar (Which the Ruby community now seems to be rightly fleeing from in abject terror) made the transition much easier for me.

                                                                                                I guess this is my wind-baggy way of saying that relative programming language readability is a highly subjective thing, so I would caution anyone against making absolute statements on this topic.

                                                                                                For instance, many programmers not used to the syntax find FORTH to be an unreadable morass of words and punctuation, whereas folks who love it inherently grok its stack based nature and find it eminently readable.

                                                                                                1. 1

                                                                                                  Oh, sure, I wasn’t trying to make a statement about general readability, but about syntax highlighting.

                                                                                                  For example, forth is basically king of being the same with and without highlighting because it’s just a stream of words. What would you even highlight? That doesn’t mean the code is readable to you, only that adding colour does the least of any syntax possible, really.

                                                                                                  Ruby has sigils for everything important and very few commonly-used keywords, so it comes pretty close also here. Sure you can highlight the few words (class, def, do, end, if) that are in common use, you could highlight the kinds of vars but they already have sigils anyway. Everything else is a method call.

                                                                                                  Basically I’m saying that highlighting shines when there are a lot of different kinds of syntax, because it helps you visually tell them apart. A language with a lot of common keywords, or uncommon kinds of literal expressions, or many built-in operators (which are effectively keywords), that kind of thing.

                                                                                                  Which is not to say no one uses syntax highlighting in ruby of course, some people find that just highlighting comments and string literals makes highlighting worth it in any syntax family, I just felt it was a weird top example for “syntax highlighting helps here”.

                                                                                                  1. 3

                                                                                                    Thank you for the clarification I understand more fully now.

                                                                                                    Unfortunately, while I can see where you’re coming from in the general case, I must respectfully disagree at least for myself. I’m partially blind, and syntax highlighting saves my bacon all the time no matter what programming language I’m using :)

                                                                                                    I do agree that Ruby perhaps has visual cues that other programming languages lack.

                                                                                                    1. 1

                                                                                                      ’m partially blind, and syntax highlighting saves my bacon all the time no matter what programming language I’m using :)

                                                                                                      If you don’t mind me asking - have you tried any Lisps, and if so, how was your experience with those? I’m curious as to whether the relative lack of syntax is an advantage or a disadvantage from an accessibility perspective.

                                                                                                      1. 1

                                                                                                        Don’t mind you asking at all.

                                                                                                        So, first off I Am Not A LISP Hacker, so my response will be limited to the years I ran and hacked emacs (I was an inveterate elisp twiddler. I wasted WAY too much time on it which is why I migrated back to Vim and now Vim+VSCode :)

                                                                                                        It was a disadvantage. Super smart parens matching helped, but having very clear visual disambiguation between blocks and other code flow altering constructs like loops and conditionals is incredibly helpful for me.

                                                                                                        It’s also one of the reasons I favor Python versus any other language where braces denote blocks rather than indentation.

                                                                                                        In Python, I can literally draw a veritcal line down from the construct and discern the boundaries of the code it effects. That’s a huge win for me.

                                                                                                        Note that this won’t eventually keep me from learning Scheme, which I’d love to do. I’m super impressed by the Racket community :)

                                                                                                    2. 1

                                                                                                      For example, forth is basically king of being the same with and without highlighting because it’s just a stream of words. What would you even highlight? That doesn’t mean the code is readable to you, only that adding colour does the least of any syntax possible, really.

                                                                                                      You could use stack effect comments to highlight the arguments to a word.

                                                                                                      : squared ( n -- n*n ) 
                                                                                                           dup * ;
                                                                                                       squared 3 .  
                                                                                                      

                                                                                                      For example, if squared is selected then the 3 should be highlighted. There’s also Chuck Moore’s ColorForth which uses color as part of the syntax.

                                                                                                2. 6

                                                                                                  Masochists (people that love pain on themselves), not sadists (people that love inflicting pain on others).

                                                                                                  1. 2

                                                                                                    Ah, thank you for the correction.

                                                                                                    I did once have a coworker who started programming ruby in hungarian notation so that they could code without any syntax highlighting, does that work?

                                                                                                    1. 4

                                                                                                      That count as both ;)

                                                                                                    2. 2

                                                                                                      Go to source is probably the only reason I use IDEs. Syntax highlighting does nothing for me. I could code entirely in monochrome and it wouldn’t affect the outcome in the slightest.

                                                                                                      On the other hand, you’re right. Tools create languages that depend on those tools. Intellij is infamous for that.

                                                                                                    3. 6

                                                                                                      You’re old and grumpy :) But seriously, the fact that it’s restricted to Github Codespaces right now limits its usefulness for a bunch of us.

                                                                                                      However, I think this kind of guided assistance is going to be huge as the rough edges are polished away.

                                                                                                      Will the grizzled veterans coding exclusively with M-x butterflies and flipping magnetic cores with their teeth benefit? Probably not, but they don’t represent the masses of people laboring in the code mines every day either :)

                                                                                                      1. 4

                                                                                                        I don’t do those things, I use languages with rich type information along with an IDE that basically writes the code for me already. I just don’t understand who would use these kinds of snippets regularly other than people building example apps or PoCs. The vast majority of code I write on a daily basis calls into internal APIs that are part of the product I work on, those won’t be in the snippet catalog this things uses.

                                                                                                        1. 4

                                                                                                          I don’t doubt it but I would also posit that there are vast groups of people churning out Java/.Net/PHP/Python code every day who would benefit enormously from an AI saying:

                                                                                                          Hey, I see you have 5 nested for loops here. Why don’t we re-write this as a nested list comprehension. See? MUCH more readable now!

                                                                                                          1. 4

                                                                                                            The vast majority of code I write on a daily basis calls into internal APIs that are part of the product I work on, those won’t be in the snippet catalog this things uses.

                                                                                                            Well, not yet. Not until they come up with a way to ingest and train based on private, internal codebases. I can’t see any reason to think that won’t be coming.

                                                                                                            1. 2

                                                                                                              Oh sure, I agree that’s potentially (very) useful, even for me! I guess maybe the problem is that the examples I’ve seen (and admittedly I haven’t looked at it very hard) seem to be more like conventional “snippets”, whereas what you’re describing feels more like a AST-based lint that we have for certain languages and in certain IDEs already (though they could absolutely be smarter).

                                                                                                              1. 2

                                                                                                                Visual studio (the full ide) has something like this at the moment and it’s honestly terrible. Always suggests inverting if statements which break the logic, or another one that I haven’t taken the time to figure out how to disable is it ‘highlights’ with a little grey line at the side of the ide (where breakpoints would be) and suggests changes such as condensing your catch blocks from try/catches onto one line instead of nice and readable.

                                                                                                                Could be great in the future if could get to what you suggested!

                                                                                                              2. 3

                                                                                                                Given that GH already has an enterprise offering, I can’t see a reason why they can’t enable the copilot feature and perform some transfer learning on a private codebase.

                                                                                                                1. 1

                                                                                                                  Is your code in GitHub? All my employer’s code that I work on is in our GitHub org, some repos public, some private. That seems like the use case here. Yeah, if your code isn’t in GitHub, this GitHub tool is probably not for you.

                                                                                                                  I’d love to see what this looks like trained on a GitHub-wide MIT licensed corpus, then a tiny per-org transfer learning layer on top, with just our code.

                                                                                                                  1. 1

                                                                                                                    Yeah, although, to me, the more interesting use-case is a CI tool that attempts to detect duplicate code / effort across the organization. Not sure how often I’d need / want it to write a bunch of boilerplate for me.

                                                                                                              3. 1

                                                                                                                it feels like a niftier autocomplete/intellisense. kind of like how gmail provides suggestions for completing sentences. I don’t think it’s world-changing, but I can imagine it being useful when slogging through writing basic code structures. of course you could do the same thing with macros in your IDE but this doesn’t require any configuration.

                                                                                                              1. 2

                                                                                                                If you dive into the C++ hello world, follow every header, every overload and trace every iostream class that is instantiated, it feels like you are sitting on a giant complex structure that was obfuscated by the deceptively simple looking abstraction which causes hello world to be flushed to stdout.

                                                                                                                1. 4

                                                                                                                  Why doesn’t the Game send an instance of Hit to the Monster instance? What in OOP stops this? Object oriented doesn’t mean that we constrain ourselves to two classes, we can still use data transfer objects.

                                                                                                                  1. 14

                                                                                                                    Can someone explain me the point of the rant? I don’t really understand what it’s trying to say.

                                                                                                                    1. 84

                                                                                                                      Every language has some core idea that inspired its creators to make it, instead of putting up with the other perfectly good languages that already existed. Sometimes, that idea is simple (“everything is an object” for Smalltalk, “everything is a cons cell” for LISP), and sometimes that idea is more complex (the way that Java is designed to scale to huge teams, or the way that Perl is “the Cliff’s Notes of Unix”).

                                                                                                                      The author’s idea is that the core idea of Ruby is (waves hands) for making domain-specific languages. It’s not the universal syntax for expressing all algorithms, but if you have an idea for how a particular algorithm should be expressed, you can probably bend Ruby into that shape, at least within a particular class or project.

                                                                                                                      The author’s lament is that Ruby’s core idea was never really named, and thus never advertised, and thus never formed part of Ruby’s reputation. As a result, it didn’t build up the audience of tinkerers and experimenters who could form a long-lived supportive community around it.

                                                                                                                      Instead, what it got was Rails, which was the opposite of that core idea: instead of bending Rails into a domain-specific language for the application you want to create, the idea is to bend your application to fit within the framework Rails provides. And since Rails became hugely popular, the vast majority of the Ruby community valued that framework-style approach and Ruby just became the incidental-complexity runtime for Rails instead of an interesting thing in its own right.

                                                                                                                      1. 11

                                                                                                                        Brilliant summary. Well done.

                                                                                                                        1. 4

                                                                                                                          The Ruby-on-Rails revolution and its consequences have been a disaster for the Ruby race.

                                                                                                                          1. 2

                                                                                                                            Can you expand a bit on the idea that Ruby is for DSLs? I feel like I’ve heard that here and there and it always seemed like a bit of a stretch. Ruby just doesn’t have things that I would think would be critical for truly writing DSLs, such as lazy evaluation and macros.

                                                                                                                            The vagrant config, for example, is a bunch of ruby code that calls itself a DSL but it really just feels like… writing ruby. Python, for instance, could do it just as well (see: SCons).

                                                                                                                            1. 5

                                                                                                                              The instance_exec method allows for succinct DSLs whose syntax couldn’t be easily copied in other languages like Python. Basically, it allows you to evaluate blocks as if they were running in the scope of an arbitrary object’s methods — or to put it in Rubyist terms, it allows you to execute blocks with an arbitrary receiver. For (a completely contrived) example, in Python you might write:

                                                                                                                              conf = Library.config_object()
                                                                                                                              conf.config_file("foo.txt")
                                                                                                                              conf.worker_processes(2)
                                                                                                                              worker = Library.worker(conf)
                                                                                                                              

                                                                                                                              Whereas a Ruby library might read:

                                                                                                                              worker = Library.worker do
                                                                                                                                config_file "foo.txt"
                                                                                                                                worker_processes 2
                                                                                                                              end
                                                                                                                              

                                                                                                                              The interior of the Ruby block defining the worker feels in a certain sense like a DSL; these methods are not in global scope: they’re special methods that are accessible inside the block, running on an anonymous object. It’s sort of like having a domain-specific language with new keywords — config_file and worker_processes — that elegantly composes with standard Ruby.

                                                                                                                              Of course, really all it means is you can leave out repeated references to conf, since Library.worker makes everything run as if it’s in the scope of some method on conf (and Ruby has implicit self inside method calls, so you can write config_file instead of self.config_file). But ergonomically it can feel nice. It’s the same number of lines, but much less significant text.

                                                                                                                              1. 1

                                                                                                                                To your point: until I read this comment, I had no idea that the Vagrant config was even supposed to be any kind of DSL. It just looked like ordinary Ruby to me.

                                                                                                                              2. 1

                                                                                                                                Thank you… Didn’t even bother reading the post - love your writing style too!

                                                                                                                                1. 1

                                                                                                                                  Thanks for that. I never learned that about ruby because the first and only place I tried it was (gross) codecademy, before I’d started learning how to code.

                                                                                                                                  1. 1

                                                                                                                                    The author’s lament is that Ruby’s core idea was never really named, and thus never advertised

                                                                                                                                    I know this is not your point, but I have a bunch of populer old books from ruby 1.9 times such as “metaprogramming ruby” and “rspec” which disagree.

                                                                                                                                  2. 5

                                                                                                                                    That Ruby never gained traction for the face value of its expressiveness. I feel that this rant imply that the mix of semantic approach of Perl and the meta-approach of Lisp meeting in the right balance in Ruby have not been recognized and exploited fully to show what Ruby really is.

                                                                                                                                    The way the author speaks about “phrase-based” reminds me of Perl, Raku, APL, dense language where you can express yourself in short understandable phrase. The author pushes the idea that this is the meaning of the mantra “Desifned for developer’s happiness”. To be happy, you have to be able to express yourself without convolution and Ruby provided that solid base and rich vocabulary to be expressive and precise.

                                                                                                                                    1. 3

                                                                                                                                      Me neither. Wondering if I should flag this as off-topic.

                                                                                                                                    1. 11

                                                                                                                                      This is a helpful article for me, thank you for posting!

                                                                                                                                      Does Lobsters allow posts like these, though? It’s a great article, but includes an ad for a service as the last section.

                                                                                                                                      1. 9

                                                                                                                                        It’s a useful article until then so it’s worth letting the votes govern its relevance, imo.

                                                                                                                                        1. 6

                                                                                                                                          I’d say there’s a difference between “here’s some useful Rust stuff, btw use our logging SaaS at the end” and “here’s why you should use our logging SaaS”

                                                                                                                                          1. 5

                                                                                                                                            Author here, glad you like it.

                                                                                                                                            I will add a conclusive sentence to make the distinction between the article and the advertisement clearer.

                                                                                                                                            1. 1

                                                                                                                                              Thanks for the article, I didn’t mind the ad. Do you inspect the stack frames non-intrusively via sampling?

                                                                                                                                            2. 4

                                                                                                                                              if it’s not too intrusive its okay, for example when you can read the article without the ad and you don’t miss big parts of the post

                                                                                                                                              1. 3

                                                                                                                                                Personally, I don’t mind it. There’s a lot of great and interesting content out there published by companies that usually includes some sort of “ad” for their service. I don’t want to cut that out just because they say, “hey, use our stuff” at the end. Especially because I can just ignore the ad bit and still learn something.

                                                                                                                                              1. 7

                                                                                                                                                Assemblers, what luxury! I wrote my first 6502 machine language programs directly in the Epyx FastLoad monitor on the C64 (a particularly deprived monitor at that) manually in hex. This is a little sad for me personally as I have no source code from my childhood projects to refer to. When my best friend and I got a KIM-1 as a weekend project in high school, it was easy for us to program, because we already knew the opcodes by heart!

                                                                                                                                                Actually being able to enter mnemonics in the C128’s MONITOR was a huge leap. Then it was TurboAssembler, and I’ve used xa65 (and now maintain it) since the late 1990s.

                                                                                                                                                1. 4

                                                                                                                                                  FastLoad! Monitors! Luxury! Kids these days not knowing what they have! When I wanted to write assembly I had to enter it as raw DATA statements in a BASIC program and write it to disk!

                                                                                                                                                  1. 3

                                                                                                                                                    Hexadecimal was a great convenience :)

                                                                                                                                                    1. 3

                                                                                                                                                      Disks! What luxury! I had to record my programs on 80s mix tapes using the 1530 datasette.