1. 20

    The response from the moderators of the Elm subreddit to this post is perhaps a good example of some of the things described by the author. Characterization of this post as abusive is something that sticks out.

    1. 6

      That reads like a copy paste that’s not actually in response to the article?

      1. 8

        They actually did lock the post. As in here’s how we prove you right.

        1. 6

          One interesting thing I immediately noticed about that is that it isn’t a single moderate (despite them having them) – it is a collective, the “elm_mods”. This feels like a shield allow the mods to be harsher than they might be as an individuals because no individual is ever responsible for the posts from “elm_mods”.

        1. 8

          As someone who is a total stranger to Elm, its dev and its community, but was interested for a long time in learning this language, I wonder if this opinion reflects the feeling of the “great number” or not.

          1. 21

            I have to say that I personally can very much see where he’s coming from. GitHub contributions are dealt with in a very frustrating way (IMO they’d do better not allowing issues and PRs at all). There’s a bit of a religious vibe to the community; the inner circle knows what’s good for you.

            That said, they may very well be successful with their approach by a number of metrics. Does it hurt to loose a few technically minded independent thinkers if the language becomes more accessible to beginners?

            Where I see the largest dissonance is in how Elm is marketed: If the language is sold as competitive to established frameworks, you’re asking people to invest in this technology. Then turning around and saying your native modules are gone and you shouldn’t complain because no one said the language was ready feels a bit wrong.

            1. 7

              Yeah when I look at the home page, it does seem like it is over-marketed: http://elm-lang.org/

              At the very least, the FAQ should probably contain a disclaimer about breaking changes: http://faq.elm-community.org/

              Ctrl-F “compatibility” doesn’t find anything.

              It’s perhaps true that pre-1.0 software is free to break, but it seems like there is a huge misunderstanding in the community about compatibility. The version number doesn’t really mean much in my book – it’s more a matter of how many people actually rely on the software for production use, and how difficult their upgrade path is. (Python 3 flauted this, but it got by.)

              I think a lot of the conflict could be solved by making fewer promises and providing some straightforward, factual documentation with disclaimers.

              I watched the “What is Success?” talk a couple nights ago and it seemed like there is a lot of unnecessary conflict and pain in this project. It sounds like there is a lot to learn from Elm though – I have done some stuff with MUV and I like it a lot. (Although, while the types and purity probably help, but you can do this in any language.)

              1. 4

                I watched the “What is Success?” talk a couple nights ago and it seemed like there is a lot of unnecessary conflict and pain in this project

                I watched the talk also, after another… Lobster(?)… Posted it in another thread. My biggest takeaway was that Evan really doesn’t want to deal with an online community. People at IRL meetups, yes. Students in college, yes. People/companies online trying to use the language? No. His leading example of online criticism he doesn’t want to deal with was literally “Elm is wrong” (he quoted without any context, which isn’t that helpful. But maybe that was all of it.)

                That’s fine. He’s the inventor of the language, and the lead engineer. He probably does have better things to do. But as an outsider it seems to me that someone has to engage more productively with the wider community. Our, just come out and say you don’t care what they think, you’ll get what you’re given, and you can use it if you choose. But either way communicate more clearly what’s going on, and what to expect.

            2. 13

              I’ve shipped multiple production applications in Elm and attempted to engage with the community and I can say that their characterization perfectly matches mine.

              Native modules being removed in particular has caused me to no longer use Elm in the future. I was always ok with dealing with any breakage a native module might cause every release, and I’m even ok with not allowing them to be published for external consumption, but to disallow them completely is unreasonable. I’m sure a number of people feel the same way as I do, but it feels impossible to provide meaningful feedback.

              1. 9

                I work for a company that began using Elm for all new projects about a year and a half ago. That stopped recently. There are several reasons that people stopped using Elm. Some simply don’t like the language. And others, like the author of this post, want to like the language but are put off by the culture. That includes me. This article closely resembles several conversations I’ve had at work in the past year.

              1. 4

                Never heard of it, but it seems like a super interesting approach to interactive environment. I cannot help but remember this Bret Victor’s talk about how we have been programming in almost-anachronistic ways with no innovation in the interfaces.

                1. 8

                  There’s nothing obsolete about text. Visual languages don’t work. They’ve been tried hundreds of times, to no avail, because GUIs are fundamentally bad user interfaces for experienced users. Text is a better interface for power users, and programming languages are for power users.

                  1. 14

                    Why can’t I re-sort the definitions in my source instead of scrolling around then? Why is it hard to see a dependency graph for all my functions? Why do I have to jump between files all the time? Text - an interface for linear presentation of information - is fundamentally a kludge for code, which is anything but linear.

                    1. 1

                      Why can’t I re-sort the definitions in my source instead of scrolling around then?

                      Sort them by what? It wouldn’t be difficult to write a script using the compiler module of Python to reorder the declarations in your file in an order you chose, which you could then use to replace the text of a buffer in your text editor. But usually I’d suggest what you want is to see a list of definitions in a particular order, which you could then use to jump to the definitions.

                      In every case that I’ve seen of not using plain text, it inevitably become inscrutable. What is actually in my Smalltalk/Lisp image? What is actually there? What can people get out of it later when I deploy it?

                      Why is it hard to see a dependency graph for all my functions?

                      Because nobody has written something that will take your source files, determine their dependencies, and produce the DOT output (a very popular text-based format for graphs, far superior in my opinion to any binary graph description format) for that graph? It’s not like it’s particularly difficult.

                      Why do I have to jump between files all the time?

                      Because it turns out it’s useful to organise things into parts. Because it turns out it’s useful to be able to parallelise compilation and not reparse every bit of code you’ve ever written every time you change any part of it.


                      I think that it’s definitely a requirement of any decent programming language to have a way to easily take the source code of that programming language and reify it into a syntax tree, for example. That’s very useful to have in a standard library. In Lisp it’s just read, Python has more complex syntax and requires more machinery which is in a standard library module, other languages have similar things.

                      One point might be: maybe you don’t need a dependency graph if you can just make your code simpler, maybe you don’t need to jump around files much if your code is properly modularised (and you have a big enough screen and narrow enough maximum line length to have multiple files open at once), maybe sorting your definitions is wrong and what you want is a sortable list of declarations you can jump to the definitions.

                      Not to mention that version control is important and version controlling things that aren’t text is a problem with conventional version control tools. Might not be an issue, you have your own VCS, but then you enter the land of expecting new users of your language to not only not use their standard editor, but also to not use their standard VCS, not use their standard pastebin, etc. How do you pastebin a snippet of a visual language so someone on an IRC channel can see it and give you help? How do you ask questions on StackOverflow about a visual language?

                      It’s not even an issue of them being unusual and unsupported. By their very nature, not using text means that these languages aren’t compatible with generic tools for working with text. And never will be. That’s the thing about text, rather than having many many many binary formats and few tools, you have one binary format and many many tools.

                      1. 8

                        Hey Miles, thanks for elaborating. I think we could have more interesting discussions if you give me a bit more credit and skip the trivial objections. You’re doing the same thing you did last time with C++ compilers. Yes, I know I could write a script, it’s not the point. I’m talking about interactive tools for source code analysis and manipulation, not a one-off sort.

                        I don’t agree with your objections about parallel compilation and parsing. It seems to me that you’re just thinking about existing tools and arguing from the status quo.

                        Further down, you make a suggestion which I interpret as “better languages could mitigate these issues” which is fair, but again I have to disagree because better languages always lead to more complex software which again requires better tools, so that’s a temporary solution at best.

                        You also raise a few objections, and here I should clarify that what I have in mind is not some kind of visual flowchart editor. What I’m claiming is that the conflation of internal representation and visual representation for code is counterproductive, but I think that a display representation that mostly looks like text is fine (as long as it’s actually within a structured editor). What I’m interested in is being able to manipulate symbols and units of code as well as aspects of its structure rather than individual characters.

                        Consequently, for pastebin or StackOverflow, you could just paste some text projection of the code, no problem. When it comes to VCS, well, the current situation is quite poor, so I’d welcome better tools there. For example, if there was a VCS that showed me diffs that take into account the semantics of the language (eg like this: https://www.semanticmerge.com), that would be pretty cool.

                        For the rest of your objections, I offer this analogy: imagine that we only had ASCII pictures, and none of this incompatible JPG/PSD/PNG nonsense with few complicated tools. Then we could use generic tools for working with text to manipulate these files, and we wouldn’t be constrained in any way whether we wanted to create beautiful paintings or complex diagrams. That’s the thing about text!

                        I think the practitioners and particularly academics in our field should have more sense of possibilities and less affection for things the way they are.

                        1. 1

                          When it comes to VCS, well, the current situation is quite poor, so I’d welcome better tools there.

                          Existing VCS could work reasonably well if the serialisation/“text projection” was deterministic and ‘stable’, i.e. minimising the amount of spurious changes like re-ordering of definitions, etc. As a first approximation I can imagine an s-expression language arranging the top-level expressions into lexicographic order, spreading them out so each sub-expression gets its own line, normalising all unquoted whitespace, etc. This would be like a very opinionated gofmt.

                          If users wan’t to preserve some layout/etc. then the editor can store that as metadata in the file. I agree that semantics-aware diffing would be great though ;)

                          1. 1

                            So you always end up separating the storage format from display representation in order to create better tools, which is exactly my point.

                            1. 1

                              Yes, I agree with your points. Was just remarking that some of these improvements (e.g. VCS) are easier to prototype and experiment with than others (e.g. semantics-aware queries of custom file formats).

                          2. 1

                            The way I see it is that there are tools for turning text into an AST and you can use them to build the fancy things you want. My point wasn’t ‘you can write that sort as a one-off’. You can edit code written in a text-based programming language with a really fancy editor that immediately parses it to an AST and works with it as an AST, and only turns it into text when written to disk. I have no problem with that. But really you’re still editing text when using something like paredit.

                            Something like vim but where the text objects are ‘identifier’, ‘ast node’, ‘expression’, ‘statement’, ‘logical line of code’, ‘block’, etc. rather than ‘text between word separators’, ‘text between spaces’, ‘line’, etc. would be a useful thing. In fact, you could probably do this in vim. I have an extension I use that lets you modify quotes around things taking into account escaped quotes within, etc. That’d probably work way better if it had that default structure for normal text and then could be customised to actually take into account the proper grammar of particular programming languages for which that is supported.

                            What I’m concerned about is the idea that it’s a good idea to store code in a proprietary binary file format that’s different for every language, where you can’t use the same tools with multiple languages. And then having to reimplement the same basic functionality for every single language in separate IDEs for each, where everything works slightly differently.

                            I do find it useful that I can do ci( and vim will delete everything inside the nearest set of parentheses, properly taking into account nesting. So if I have (foo (hello 1 2 3) bar) and my cursor is on the a, it’ll delete everything, even though the nearest ( and ) are beside hello and not foo. That kind of thing, more structured editing? I’m all for that.

                            Consequently, for pastebin or StackOverflow, you could just paste some text projection of the code, no problem. When it comes to VCS, well, the current situation is quite poor, so I’d welcome better tools there. For example, if there was a VCS that showed me diffs that take into account the semantics of the language (eg like this: https://www.semanticmerge.com), that would be pretty cool.

                            Ultimately I think if you have a recognised standardised text projection of your code, you might as well just make that the standardised format for it, then your fancy editor or editor plugin can parse it into the structures it needs. This helps ensure you can edit code over SSH, and have a variety of editors compatible with it, rather than just the single language-designer-provided IDE.

                            One of the nice things about git is that it stores snapshots internally rather than diffs. So if you have a language-specific tool that can produce diffs that are better due to being informed by the grammar of the language (avoiding the problem of adding a function and the diff being ‘added a new closing brace to the previous function then writing a new function except for a closing brace’, for example), then you can do that! Change the diff algorithm.

                            For the rest of your objections, I offer this analogy: imagine that we only had ASCII pictures, and none of this incompatible JPG/PSD/PNG nonsense with few complicated tools. Then we could use generic tools for working with text to manipulate these files, and we wouldn’t be constrained in any way whether we wanted to create beautiful paintings or complex diagrams. That’s the thing about text!

                            Well I mean I do much prefer creating a graph by writing some code to emit DOT than by writing code to emit PNG. I did so just the other day in fact. http://rout.nz/nfa.svg. Thank god for graphviz, eh?

                            Note that there’s also for example farbfeld, and svg, for that matter: text-based formats for images. Just because it’s text underneath doesn’t mean it has to be rendered as ASCII art.

                            1. 1

                              Cool, I’m glad we can agree that better tools would be good to have.

                              As far as the storage format, I don’t actually have a clear preference. What’s clearly needed is a separation of storage format and visual representation. If we had that, arguments about tabs vs spaces, indent size, let/in vs where, line length, private methods first or public methods first, vertical vs horizontal space (and on and on) could be nullified because everybody could arrange things however they like. Why can’t we have even such simple conveniences? And that’s just the low hanging fruit, there are far more interesting operations and ways of looking at source that could be implemented.

                              The other day there was a link to someone’s experiment (https://github.com/forest-lang/forest-compiler) where they use one of the text projections as the storage format. That might work, but it seems to me that the way parsing currently happens, there’s a lot of unnecessary work as whole files are constantly being reparsed because there is no structure to determine the relevant scope. It seems that controlling operations on the AST and knowing which branches are affected could be a lot more efficient. I’m sure there’s plenty of literature of this - I’ll have to look for it (and maybe I’m wrong about this).

                              What I’m concerned about is the idea that it’s a good idea to store code in a proprietary binary file format that’s different for every language, where you can’t use the same tools with multiple languages. And then having to reimplement the same basic functionality for every single language in separate IDEs for each, where everything works slightly differently.

                              I understand your concern, but this sounds exactly like the current state of affairs (other than really basic stuff like syntax highlighting maybe). There’s a separate language plugin (or plugins) for every combination of editor/IDE and language, and people keep rewriting all that stuff every time a new editor becomes popular, don’t they?

                              One of the nice things about git is that it stores snapshots internally rather than diffs.

                              Sure, we can glean a bit more information from a pair of snapshots, but still not much. It’s still impossible to track a combination of “rename + change definition”, or to treat changes in the order of definitions as a no-op, for example. Whereas if we were tracking changes in a more structured way (node renamed, sub-nodes modified etc.), it seems like we could say a lot more meaningful things about the evolution of the tree.

                              Thank god for graphviz, eh?

                              Perhaps the analogy was unclear. Being able to write a set of instructions to generate an image with a piece of software has nothing to do with having identical storage format and visual representation. If we approached images the same way we approach code, we would only have ASCII images as the output format, because that’s what is directly editable with text tools. Since you see the merits of PNG and SVG, you’re agreeing that there’s merit in separating internal/storage representation from the output representation.

                              1. 1

                                What I’m concerned about is the idea that it’s a good idea to store code in a proprietary binary file format that’s different for every language

                                I might have missed something, but I didn’t see anyone proposing this.

                                In particular, my understanding of Luna is that the graphical and textual representations are actually isomorphic (i.e. one can be derived if given the other). This means we can think of the textual representation as the being both a traditional text-based programming language and as a “file format” for serialising the graphical programming language.

                                Likewise we can switch to a text view, use grep/sed/etc. as much as we like, then switch back to a graphical view if we want (assuming that the resulting text is syntactically valid).

                          3. 1

                            Tools that improve navigation within textual source have existed for a long time. I’ve been using cscope to bounce around in C and Javascript source bases for as long as I can remember. The more static structure a language has, the easier it is to build these tools without ambiguity. The text source part isn’t really an issue – indeed it enables ad hoc tooling experiments to be built with existing text management tools; e.g., grep.

                            1. 4

                              Those tools aren’t text, though. They’re other things the augment the experience over just using text which becomes an incidental form of storage. Tools might also use AST’s, objects, data flows, constraints, and so on. They might use anything from direct representation to templates to synthesis.

                              I think the parent’s point was just text by itself is far more limited than that. Each thing I mentioned is available in some programming environment with an advantage over text-driven development.

                              1. 1

                                I think it’s wrong to say that the text storage is incidental. Line-oriented text files are about the lowest common denominator way we have to store data like this.

                                For starters, it’s effectively human-readable – you can lift the hood up and look at what’s underneath, understanding the effect that each individual character has on the result. Any more complicated structure, as would be generally required to have a more machine-first structured approach to program storage, is not going to have that property; at least not to the same extent.

                                If this thread demonstrates anything, it’s that we all have (at times, starkly!) different preferences for software engineering tools. Falling back on a textual representation allows us to avoid the need to seek consensus on a standard set of tools – I can use the editor and code manipulation tools that make sense to me, and you can stick to what makes sense to you. I think a lot of the UNIX philosophy posturing ends up being revisionist bunk, but the idea that text is a pretty universal interface for data interchange isn’t completely without merit.

                                1. 6

                                  The under-the-hood representation is binary-structured electricity that gets turned into human-readable text by parsing and display code. If already parsing it and writing display code, then one might just as well use a different encoding or structure. Text certainly has advantages as one encoding of many to have available. Plugins or input modules can take care of any conversions.

                                  Text does often have tooling advantages in systems like UNIX built with it in mind, though.

                                  1. 1

                                    I think it’s a reductionist argument for the good-enough, hard earned status quo. I think it can be valid, but only within a very narrow perspective - operational and short term.

                                    To my mind, your position is equivalent to this: we should only have ASCII images, and we don’t need any of that PNG/JPG/PSD stuff with complicated specialised tools. Instead, we can use generic text tools to make CAD drawings, diagrams, paintings - whatever. All of those things can be perfectly represented in ASCII, and the text tools will not limit us in any way!

                                2. 2

                                  I want to search my code like a database, e.g. “show my where this identifier is used as a parameter to a function” - the tooling for text doesn’t support this. Structured tooling would be super useful.

                                  1. 2

                                    Many things can be “queried” with grep and regular expressions. Which is also great to find “similar occurrences” that need to be checked but are only related by some operators and function calls following another. But on the other hand I’d definitely argue that IDEs at least have a tiny representation of the current source file for navigation or something and that you can click some token and find its uses, definitions, implementations … But it only works if I disable the low power mode. And with my 8Gb RAM MacBook I sometimes have to kill the IDE before running the program to make sure I can still use it at the same time.

                                    1. 7

                                      Maybe if it wasn’t parsing and re-parsing massive amounts of text all the time, it would be more energy efficient…

                                    2. 1

                                      Exactly. And it could extend beyond search; code could be manipulated and organised in more powerful ways. We still have rudimentary support for refactoring in most IDEs, and so we keep going through files and manually making structurally similar changes one by one, for no reason other than the inadequate underlying representation used for code.

                                      I could be wrong and maybe this is impossible to implement in any kind of general way beyond the few specific examples I’ve thought of, but I find it strange that most people dismiss the very possibility of anything better despite the fact that it’s obviously difficult and inconvenient to work with textual source code.

                                      1. 1

                                        The version of cscope that I use does things of that nature. The list of queries it supports:

                                        Find this C symbol:
                                        Find this global definition:
                                        Find functions called by this function:
                                        Find functions calling this function:
                                        Find this text string:
                                        Change this text string:
                                        Find this egrep pattern:
                                        Find this file:
                                        Find files #including this file:
                                        Find assignments to this symbol:
                                        

                                        I use Find functions calling this function a lot, as well as Find assignments to this symbol. You could conceivably add more query types, and I’m certain there are other tools that are less to my admittedly terminal-heavy aesthetic preference that offer more flexible code search and analysis.

                                        The base structure of the software being textual doesn’t get in the way of this at all.

                                        1. 3

                                          Software isn’t textual. We read the text into structures. Our tools should make these structures easier to work with. We need data structures other than text as the common format.

                                          Can I take cscope’s output and filter down to “arguments where the identifiers are of even length”?

                                          1. 5

                                            Compilers and interpreters use structured representations because those representations are more practical for the purposes of compiling and interpreting. It’s not a given that structured data is the most practical form for authoring. It might be. But what the compiler/interpreter does is not evidence of that.

                                            1. 1

                                              Those representations are more practical for searching and manipulating. Try it!

                                            2. 1

                                              I would also be interested on your thoughts about Lisp where the code is already structured data. This is an interesting property of Lisp but it does not seem to make it clearly easier to use.

                                              1. 2

                                                but it does not seem to make it clearly easier to use.

                                                Sure it does: makes macros easier to write than a language not designed like that. Once macros are easy, you can extend the language to more easily express yourself. This is seen in the DSL’s of Common LISP, Rebol, and Racket. I also always mention sklogic’s tool since he DSL’s about everything with a LISP underneath for when they don’t work.

                                        2. 2

                                          Sure, but all of these tools (including IDEs) are complicated to implement, error-prone, and extremely underpowered. cscope is just a glorified grep unless I’m missing something (I haven’t used it, just looked it up). The fact that you bring it up as a good example attests to the fact that we’re still stuck somewhere near mid-twentieth century in terms of programming UI.

                                          1. 4

                                            I bring it up as a good example because I use it all the time to great effect while working on large scale software projects. It is relatively simple to understand what it does, it’s been relatively reliable in my experience, and it helps a lot in understanding the code I work on. I’ve also tried exuberant ctags on occasion, and it’s been pretty neat as well.

                                            I don’t feel stuck at all. In fact, I feel wary of people attempting to invalidate positive real world experiences with assertions that merely because something has been around for a long time that it’s not still a useful way to work.

                                      2. 2

                                        Have you noted, that the Luna language has dual representation? Where each visual program has an immediate and easily editable text representation, and the same is true in the other direction as well? This is intended to be able to keep the benefits of the text interface, while adding the benefits of a visual representation! That’s actually the main idea behind Luna.

                                        1. 1

                                          What about the power users who use things like Excel or Salesforce? These are GUIs perfectly tailored to specific tasks. A DJ working with a sound board certainly wouldn’t want a textual interface.

                                          Textual interfaces are bad, but they are generic and easy to write. It’s a lot harder to make an intuitive GUI, let alone one that works on something as complex as a programming language. Idk if Luna is worthwhile, but text isn’t the best user interface possible imho

                                          1. 3

                                            DJs use physical interfaces, and the GUIs emulation of those physical interfaces are basically all terrible.

                                            I’ve never heard of anyone liking Salesforce, I think that must be Stockholm Syndrome. Excel’s primary problem in my opinion is that it has essentially no way of seeing how data is flowing around. If something had the kind of ‘reactive’ nature of Excel while being text-based I’d much prefer that.

                                            Textual interfaces are excellent. While there are tasks that benefit from a GUI - image editing for example - in most cases GUIs are a nicer way of representing things to a new user but are bad for power users. I wouldn’t expect first year computer science students to use vim, as it’s not beginner-friendly, but it’s by far the best text editor out there in the hands of an experienced user.

                                            1. 2

                                              I wouldn’t expect first year computer science students to use vim, as it’s not beginner-friendly, but it’s by far the best text editor out there in the hands of an experienced user.

                                              I’d call myself an “experienced user” of vim. I’ve written extensions, given workshops, and even written a language autoindent plugin, which anyone who’s done it knows is like shoving nails through your eyeballs. About once a year I get fed up with the limitations of text-only programming and try to find a good visual IDE, only to switch back when I can’t find any. Just because vim is the best we currently have doesn’t mean it’s actually any good. We deserve better.

                                              (For the record, vim isn’t beginner-unfriendly because it’s text only. It’s beginner-unfriendly because it’s UI is terrible and inconsistent and the features are all undiscoverable.)

                                              1. 2

                                                Most people don’t bother to learn vimscript properly, treating it much like people treated Javascript for years: a bunch of disparate bits they’ve picked up over time, with no unifying core. But once you actually learn it, it becomes much easier to use and more consistent. The difference between expressions and commands becomes sensible instead of seeming like an inconsistency.

                                                I never get fed up with the limitations of text-only programming, because I don’t think they exist. Could you elaborate on what you are saying those limitations are?

                                                And I totally, 100% disagree with any claim that vim’s UI is bad or inconsistent. On the contrary, it’s extremely consistent. It’s not a bunch of little individual inconsistent commands, it’s motions and text objects and such. It has extensive and well-written help. Compared to any other IDE I’ve used (a lot), it’s way more consistent. Every time I use a Mac program I’m surprised at how ad-hoc the random combinations of letters for shortcuts are. And everything requires modifier keys, which are written with ridiculous indecipherable symbols instead of ‘Ctrl’ ‘Shift’ ‘Alt’ etc. Given that Mac is generally considered to be very easy to use, I don’t think typical general consensus on ease of use is very instructive.

                                        2. 3

                                          Bret Victor explains the persistence of textual languages as resistance to change, drawing an equivalence between users of textual languages now and assembly programmers who scoffed at the first higher-level programming languages. But this thread is evidence that at least some people are interested in using a language that isn’t text-based. Not everyone is fairly characterized by Bret Victor’s generalization. So then why hasn’t that alternative emerged? There are plenty of niche languages that address a minority preference with reasonable rates of adoption. With the exception of Hypercard, I can’t think of viable graphical programming language. Even Realtalk, the language that runs Dynamicland (Bret Victor’s current focus), is text-based, being a superset of Lua. I keep hearing about how text-based languages are old-fashioned and should die out, but I never hear anything insightful about why this hasn’t happened naturally. I’m not denying that there are opportunities for big innovation but “make a visual programming language” seems like an increasingly naive or simplistic approach.

                                          1. 4

                                            I think it has to do with the malleability of text. There’s a basic set of symbols and one way to arrange them (sequentially.) Almost any problem can be encoded that way. Emacs’ excellent org-mode is a testament to the virtue of malleability.

                                            Excel also has that characteristic. Many, many kind of problems can be encoded in rectangles of text with formulas. (Though I might note that having more ways to arrange things allows new kinds of errors, as evidenced by the growing cluster of Excel features for tracing dependencies & finding errors.)

                                            Graphical languages are way less malleable. The language creator decides what elements, relations, and constraints are allowed. None of them let me redefine what a rectangle represents, or what relations are allowed between them. I think that’s why these languages can be great at solving one class of problem, but a different class of problem seems to require a totally different graphical language.

                                            1. 1

                                              My suspicion is that it’s because graphical languages merge functionality and aesthetics, meaning you have to think very, VERY hard about UI/UX and graphic design. You need to be doing that from the start to have a hope of it working out.

                                          1. 1

                                            One way an organization can avoid this kind of behavior is to involve developers in the conceptualization of the product. All products have lots of hard and unsolved problems. But in my experience, they are often conceptual problems. When the developer is one of the people forming and testing hypotheses about what would be good for the user, mundane technical work becomes just the last step in achieving something that is challenging and fulfilling: a product that people find useful.

                                            1. 2

                                              I’m not sure it’s correct to assume that copyright is meant to incentivize those who have already created to keep creating. It’s just meant to incentivize creation. If that means that the “overpaid” creators cease producing, there is still everyone else working to achieve that “overpaid” state. So people are still incentivized even if the same one person does not remain incentivized. This doesn’t seem inconsistent with the theory of copyright.

                                              1. 10

                                                This is the same tired argument in favor of static typing that you see in every blog. The problem is that while the arguments sound convincing on paper, there appears to be a serious lack of empirical evidence to support many of the benefits ascribed to the approach. Empiricism is a critical aspect of the scientific method because it’s the only way to separate ideas that work from those that don’t.

                                                An empirical approach would be to start by studying real world open source projects written in different languages. Studying many projects helps average out differences in factors such as developer skill, so if particular languages have a measurable impact it should be visible statistically. If we see empirical evidence that projects written in certain types of languages consistently perform better in a particular area, such as reduction in defects, we can then make a hypothesis as to why that is.

                                                For example, if there was statistical evidence to indicate that using Haskell reduces defects, a hypothesis could be made that the the Haskell type system plays a role here. That hypothesis could then be further tested, and that would tell us whether it’s correct or not. This is pretty much the opposite of what happens in discussions about static typing however, and it’s a case of putting the cart before the horse in my opinion.

                                                The common rebuttal is that it’s just too hard to make such studies, but I’ve never found that to be convincing myself. If showing the benefits is truly that difficult, that implies that static typing is not a dominant factor. One large scale study of GitHub projects fails to show a significant impact overall, and shows no impact for functional languages. At the end of the day it’s entirely possible that the choice of language in general is eclipsed by factors such as skill of the programmers, development practices, and so on.

                                                I think it’s important to explore different approaches until such time when we have concrete evidence that one approach is strictly superior to others. Otherwise, we risk repeating the OOP hype when the whole industry jumped on it as the one true way to write software.

                                                1. 6

                                                  One large scale study of GitHub projects fails to show a significant impact overall, and shows no impact for functional languages.

                                                  That is not the language used by the authors of the paper:

                                                  The data indicates functional languages are better than procedural languages; it suggests that strong typing is better than weak typing; that static typing is better than dynamic; and that managed memory usage is better than un-managed.

                                                  1. 2

                                                    Look at the actual results in the paper as opposed to the language.

                                                  2. 3

                                                    Annecdote but Typescript exists purely to make an existing language use static types. It has near universal appeal among those who have tried it, and in my experience an entire class of errors disappeared overnight while being having almost no cost at all apart from the one-time transition cost

                                                    Meanwhile “taking all projects will average things out” is unlikely to work well. Language differences are rarely just about types, and different languages have different open source communities with different skill levels and expectations

                                                    1. 3

                                                      As much as I like empiricism and the “there’s not actually that much difference” hypothesis, that article has flaws. In particular, it has sloppy categorization, fex classifying bitcoin as “typescript”. Also, some of its conclusions set off my “wait what” meter, such as Ruby being much safer than python and typescript being the safest language of all.

                                                      1. 3

                                                        The study has many flaws, and by no means does it provide any definitive answers. I linked it as an example of people trying to approach this problem empirically. My main point is that this work needs to be done before we can meaningfully discuss the impacts of different languages and programming styles. Absent empirical evidence we’re stuck relying on our own anecdotal experiences, and we have to be intellectually honest in that regard.

                                                      2. 2

                                                        That link doesn’t seem to be working. Is this the same study?: http://web.cs.ucdavis.edu/~filkov/papers/lang_github.pdf

                                                        I think you make very good points (even though I currently have a preference for static types). I’d love to see more empirical evidence.

                                                        1. 1

                                                          Thanks, and that is the same study. It’s far from perfect, but I do think the general idea behind it is on the right track.

                                                          1. 2

                                                            I only skimmed the study, but doesn’t it actually show a small positive effect for functional languages? From the study:

                                                            Result 2: There is a small but significant relationship between language class and defects. Functional languages have a smaller relationship to defects than either procedural or scripting languages.

                                                            I realise that overall language had a small effect on defect rate, and they noted that it could be due to factors like the kind of people attracted to a particular language, rather than language itself.

                                                            1. 4

                                                              The results listed show a small positive effect for imperative languages, and no effect among functional ones. In fact, Clojure and Erlang appear to do better than Haskell and Scala pretty much across the board:

                                                              lang/bug fixes/lines of code changed
                                                              Clojure  6,022 163
                                                              Erlang  8,129 1,970
                                                              Haskell  10,362 508
                                                              Scala  12,950 836
                                                              
                                                              defective commits model
                                                              Clojure −0.29 (0.05)∗∗∗
                                                              Erlang −0.00 (0.05)
                                                              Haskell −0.23 (0.06)∗∗∗
                                                              Scala −0.28 (0.05)∗∗∗
                                                              
                                                              memory related errors
                                                              Scala −0.41 (0.18)∗
                                                              0.73 (0.25)∗∗ −0.16 (0.22) −0.91 (0.19)∗∗∗
                                                              Clojure −1.16 (0.27)∗∗∗ 0.10 (0.30) −0.69 (0.26)∗∗ −0.53 (0.19)∗∗
                                                              Erlang −0.53 (0.23)∗
                                                              0.76 (0.29)∗∗ 0.73 (0.22)∗∗∗ 0.65 (0.17)∗∗∗
                                                              Haskell −0.22 (0.20) −0.17 (0.32) −0.31 (0.26) −0.38 (0.19)
                                                              

                                                              The study further goes to caution against overestimating the impact of the language:

                                                              One should take care not to overestimate the impact of language on defects. While these relationships are statistically significant, the effects are quite small. In the analysis of deviance table above we see that activity in a project accounts for the majority of explained deviance. Note that all variables are significant, that is, all of the factors above account for some of the variance in the number of defective commits. The next closest predictor, which accounts for less than one percent of the total deviance, is language.

                                                              This goes back to the original point that it’s premature to single out static typing as the one defining feature of a language.

                                                      1. 1

                                                        Here’s an example from this post:

                                                        export default handleActions (
                                                          {
                                                            ADD_TODO: (state, action) => {
                                                              return {
                                                                ...state,
                                                                currentTodo: '',
                                                                todos: state.todos.concat (action.payload),
                                                              };
                                                            },
                                                            LOAD_TODOS: (state, action) => {
                                                              return {
                                                                ...state,
                                                                todos: action.payload,
                                                              };
                                                            },
                                                            UPDATE_CURRENT: (state, action) => {
                                                              return {
                                                                ...state,
                                                                currentTodo: action.payload,
                                                              };
                                                            },
                                                            REPLACE_TODO: (state, action) => {
                                                              return {
                                                                ...state,
                                                                todos: state.todos.map (
                                                                  t => (t.id === action.payload.id ? action.payload : t)
                                                                ),
                                                              };
                                                            },
                                                            REMOVE_TODO: (state, action) => {
                                                              return {
                                                                ...state,
                                                                todos: state.todos.filter (t => t.id !== action.payload),
                                                              };
                                                            },
                                                            [combineActions (SHOW_LOADER, HIDE_LOADER)]: (state, action) => {
                                                              return {...state, isLoading: action.payload};
                                                            },
                                                          },
                                                          initState
                                                        );
                                                        

                                                        To me this and Redux in general both look like a half-baked reimplement of JavaScript’s class, except the method names are UPPER_CASE because they are “constant”, and state is managed elsewhere and passed as a parameter instead of being stored on this. Why reinvent this syntax? Is it just so we can be sure we’re using “functional programming” and have “no internal state”?

                                                        If you want to eliminate boilerplate, cut the knot. Let me write my reducer as a class, and then generate the action creators, action names, etc from the class’s declared methods. You can still have all the benifits of redux while using a pleasing syntax.

                                                        A sketch (pardon, on mobile):

                                                        class TodoReducer extents Reducer {
                                                          static initialState = () => ({ ... })
                                                        
                                                          addTodo(state, todo) {
                                                            return {
                                                              ...state,
                                                              currentTodo: '',
                                                              todos: state.todos.concat(todo),
                                                            }
                                                          }
                                                        
                                                          // more methods ...
                                                        }
                                                        
                                                        // each camel-case methodName has a constant case METHOD_NAME.
                                                        // Returns an object with each constant case method name mapped to itself. 
                                                        export const actions = TodoReducer.actions()
                                                        
                                                        // creates an object mapping methodNames to functions that return an action object with type 
                                                        // set to the constant case name of that method
                                                        export const actionCreators = TodoReducer.actionCtreators
                                                        
                                                        // creates a reducer function from the class that handles dispatching redux actions as regular method calls on an instance of the class.
                                                        // the wrapper function could also do hand-holding like assert there is no state being recorded in the instance
                                                        // or, a new instance could be created for each dispatch, although the perf would suck
                                                        export const reducer = TodoReducer.reducer()
                                                        
                                                        1. 1

                                                          Personally I’d much rather avoid method-name magic, and I find splitting actions/constants/reducer into 3 flies in a module is an easy way to organise it, even if it is a fair chunk of boilerplate, and it all ends up seeming a lot simpler and less overblown than that example where it’s all done inline. Yes it could totally be more concise, but I really like explicit. Just my opinion, obvs.

                                                          1. 1

                                                            To me, the core benefits of redux are:

                                                            1. All (important) state in one spot: simplifies reasoning and decision making
                                                            2. Dependency injection: callers and consumers both have no knowledge of the state holder
                                                            3. serializability: actions are simple objects that can be recorded, streamed across the network, replayed, ….

                                                            What’s the purpose of the CONSTANTS file? How do you use those constants, other than to put them in the { type: } field of a serializable action, or to reason about an action in a reducer?

                                                            How does moving the method names of a class into another file improve organization? What benefits do you see in an explicit composition from parts usually left implicit in other patterns?

                                                            (As for the CONSTANT_NAME magic proposed in my example: sure, it’s immaterial. Trade following redux style convention for less magic.)

                                                            1. 1

                                                              I think those are the core benefits too :-) No purpose for such files other than to keep everything in one place, make it easily accessible, and know easily where I am with everything, and never have to remember name-conversion conventions or any of that stuff. Nothing more - but for my way of working it’s clearer and easier.

                                                          2. 1

                                                            One reason is that actions and reducers share a one to many relationship. You can decompose a single reducer into several reducers and potentially all of those reducers handle the same action. Actions are not meant to be remote function calls.

                                                          1. 5

                                                            Howdy - recovering generative artist here [0]

                                                            Everything the artist says in this essay is correct. The lost connection between creator and observer hurts generative art. The art community is interested in emotional expression and connecting with the purpose of invoking something new and interesting. I wrote a long treatise about this some years back, attempting to coin the term Artificial Expression [1] (which is partially obsolete with the advent of deep learning but the overall point still stands).

                                                            Sometimes I wish it weren’t true. Sometimes I wished that technically beautiful stuff was appreciated by everyone without that pesky emotional connection, but it’s not. The same goes for technically proficient photo-realistic artwork. People say “That’s cool” and then move on to something they can actually bond with on another level.

                                                            But that’s important! It’s important because we’re humans and we suffer from the human condition. So the things that take us out of that plane and let us engulf ourselves in pure emotion is the best kind of art. We’re made a certain way genetically, culturally, and socially - and that’s the good stuff right there. Finding this for yourself as an artist is the most important thing. Once you get out of the rut of trite technicality and see the world for what it is, you’ll be better for it.

                                                            [0] Shameless plug for some of my stuff- http://binarymax.com/tree.html , http://binarymax.com/randriaan.html , https://max.io/jewels24.html , http://binarymax.com/backgammon/

                                                            [1] https://max.io/articles/theories-on-artificial-expression/

                                                            1. 1

                                                              So the things that take us out of that plane and let us engulf ourselves in pure emotion is the best kind of art. We’re made a certain way genetically, culturally, and socially - and that’s the good stuff right there.

                                                              Do you have any data to support sweeping generalizations like this? How can this theory explain things like Gothic architecture that were created over decades by groups of craftsmen who were focused on mastering and practicing technique? Many of the stone masons did not know what emotional impact their work would elicit. Isn’t it more likely that “people say ‘That’s cool’ and then move on” when what you’re showing them is only that interesting?

                                                              1. 3

                                                                I do not have access to a formal study that definitively defines captivating art. The accepted definition of art is communication of expression from a creator to an observer. I will take the opportunity to focus on your use of the term ‘craftsmen’. Craft is not art. Technically proficient craft is absolutely admired for what it is, but the lack of emotional connection or purposeful expression to forge that connection is why it differs from art.

                                                                1. 1

                                                                  @binarymax, FYI, randriaan doesn’t seem to work in Firefox 63.0a1 (2018-07-09) (64-bit) on Windows.

                                                                  1. 1

                                                                    Hey thanks for the heads up - but I don’t have a Windows box so can’t debug. It works fine on my Firefox 61.0.1 (64-bit) in MacOS. Do you see any kind of error/warning in the console?

                                                                    1. 1

                                                                      Oh, it works if I click the link and open it in this tab. If I ctrl+click or third-button click to open it in a new tab, it doesn’t work, but then it does work when I ctrl+F5 to hard-refresh it.

                                                              1. 5

                                                                Generative artwork has been dominated by the intelligent and the intellectual. It has been obsessed with the discovery of clever algorithms and optimizations.

                                                                I think the author should provide evidence of his premise. I can’t think of any generative art where the method was emphasized more than the outcome. Maybe my experience is an exception to the rule.

                                                                Secondly, I’m not sure that the method doesn’t matter. He makes some very broad generalizations about the audience: “the viewer doesn’t give a shit if Rothko ground his own pigment by hand.” I don’t know how many viewers tend to care about that detail of Rothko’s work in particular. But I think many viewers do care about the methods used to produce Sol Lewitt’s Instruction-based art. And those works, which are essentially algorithms manually executed by assistants, are a much closer analogue to generative art produced with a computer. It is banal to point out that people, both artists and audience, are different and will find meaning in different things. Some people find the method meaningful. Others don’t. This should be something we all already understand.

                                                                In general, this piece lacks nuance and fails to meet a basic standard for critical thinking.

                                                                1. 3

                                                                  I can’t think of any generative art where the method was emphasized more than the outcome.

                                                                  Algorithmic symphonies from one line of code and Some deep analysis of one-line music programs.

                                                                  1. 2

                                                                    What’s completely missing from the article is that inspiration often comes through process and as a product of the repeated, practiced application of process.

                                                                    Agnes Martin’s work is a great example, it’s dense and obsessive and preternaturally powerful, she spent years and years doing it over and over, her work got denser and more powerful the more she did it and as far as I can tell the inspiration happened in tandem(/symbiosis) with or as a function of her relentless work on it. Sure there can be an inspiration to make a great work but without the skill and the process required to realise it the great work doesn’t happen.

                                                                    Rothko’s process was fundamental, and because we don’t have any Rothko work to which he didn’t apply his process, we have no way of knowing whether art he produced without doing so would have been able to produce the extraordinarily deep and emotionally rich work he produced with it. I’m no expert but I’m guessing no, the reason the work is so strong is not only the process nor only the inspiration but a combination of the two, honed and enriched by years of practice, until the process and the inspiration are completely intertwined and function as one. Which is why his work was so extraordinary and why he was such an extraordinary talent. And why it probably makes a great deal of difference to the viewer that he ground his own pigment, even if they’re not aware of it, because that was necessary to achieve the inspired effect he was aiming for.

                                                                    And - here’s the point - all of this is why it’s so incredibly rare to get genuinely good, meaningful generative art, because the mix of sufficient technical skill with sufficient artistic inspiration is so damn rare, and (in my view at least) a majority of it is people who are good at math or geometry or OpenGL and fancy themselves as artists, but are far from that, because they either haven’t got the natural inspiration as a starting-point or they haven’t spent long enough developing it yet.

                                                                    So yes, of course an overly intellectual focus will likely produce a less emotionally connecting or inspired piece of work - but pure emotion or inspiration without technical capability, at least in something as fundamentally technically complex as generative art, will likely produce works that just aren’t very good. Arguing it should be more of one aspect than the other seems to me to be missing the point.

                                                                    (Post written on the bus in a moment of inspiration subsequently edited on the desktop for technical correctness and, uh, coherence)

                                                                  1. 9

                                                                    After 2 years my experience with Vue has been positive. I’m still confident it was a good decision to move my team from React to Vue. Not because Vue is better, but because it is a better fit for us.

                                                                    Why though? These comparisons of libraries/frameworks that amount to “differences of technical details” are not worth writing. Did the author have some problem that couldn’t be solved with React and could be solved with Vue? That would be worth hearing about. I’m talking real business-value-added problem solving. Not “the syntax is nicer”. If I was employing this author and read this article, I would feel like the migration from React to Vue had been a waste of company resources.

                                                                    1. 1

                                                                      Well ultimately they are both Javascript frameworks, so what you can do in one you can do in another, the whole idea of a framework is the syntax in which you interact with it to the base language. As such, some things will be easier in framework X and other will be easier in framework Y. In my opinion you have the Angular way to solve JS “framework projects”, then the React way, Vue sits a bit in the middle (if not closer to React).

                                                                      1. 2

                                                                        what you can do in one you can do in another

                                                                        If I’m already using a tool that can do what I need it to do, why would I invest in a new tool? And I don’t mean to reduce things to “it’s all JavaScript so you don’t need a library”. React, Angular, Ember, Vue, etc., are compelling to me to the degree that they enable a developer/organization to deliver useful software. But if React and Vue are compelling to the same degree, I’m not sure there’s anything to talk about.

                                                                      2. 1

                                                                        Author here.

                                                                        The article was getting pretty long already and I didn’t want to get into those points.

                                                                        Did the author have some problem that couldn’t be solved with React and could be solved with Vue?

                                                                        There were 3 major paint points for us with React. That was in 2015-2016, at the end of 2016 we moved to Vue.

                                                                        1. JSX is ok for JS devs, but terrible for designers that work with HTML and CSS. We tried to solve that using a Wix library called react-templates but it introduced its own set of problems.

                                                                        2. React Router was cumbersome compared to Vue Router. For example if you need to access the router from a component you needed to create a HOC. We also hit a bug that could only be solved by using setTimeout() with 0 delay. We quickly found that the React Router team was not very welcoming to feature requests or bug reports, to put it mildly. Vue Router in comparison made a lot more sense and was much easier to deal with.

                                                                        3. Managing local state compared to Vue is tedious. We considered moving to MobX, which is what a lot of React guys are doing, but at that point I gave Vue a try and it was immediately clear that it was a better fit for us.

                                                                        If I was employing this author and read this article, I would feel like the migration from React to Vue had been a waste of company resources.

                                                                        We didn’t rewrite our React projects to Vue, if that’s what you are implying.

                                                                      1. 1

                                                                        Always useful to see how real problems can be solved, particularly in this case through the use of the Observable pattern. Found the link to the tc39 observable discussion invaluable - many thanks.

                                                                        1. 1

                                                                          I’m glad. Thanks for reading!

                                                                        1. 8

                                                                          Things like this are why I laugh whenever people claim javascript is “taking over”.

                                                                          Even fucking php has const’s that are actually constant.

                                                                          1. 3

                                                                            Honestly the only people that believe JavaScript is taking over are people who haven’t used anything else.

                                                                            1. 2

                                                                              And yet it’s everywhere. If any language is really “taking over”, it’s JS. It’s mandatory in the browser, and it’s optional almost everywhere else.

                                                                              1. 1

                                                                                That’s why it’s so big. If you want to learn only one language it has to be JS.

                                                                                1. 1

                                                                                  You think javascript is mandatory to make a website or web app?

                                                                              2. 2

                                                                                But this feature (preventing mutation of mutable structures recursively) is uncommon. So far I’ve seen it only in PHP and Rust. What other languages has it too?

                                                                                1. 3

                                                                                  recursive mutation is not even the issue, const in JavaScript just means “I will not reassign this reference” so even the top-level value is mutable. You can const a=[]; a.push({});

                                                                                  1. 1

                                                                                    If top-level mutation prevention can be implemented, then all levels down is not that hard, I think. But I can’t imagine how to do it in languages with pass-everything-by-reference semantics, and most languages have such semantics (js, java, python, ruby, etc).

                                                                                    Some of such languages has “constant binding” feature too, i.e. java’s final, which lots of users find useless, and still I see lots of final in java code. Clojure has let which is similar to having only const in js, and it also can’t prevent mutation of underlying objects:

                                                                                    => (let [a (java.util.LinkedList.)] (.add a "foo") a)
                                                                                    ("foo")
                                                                                    

                                                                                    So while mutation by calling methods can’t be prevented at all in js, and it’s not surprising behavior, mutation of captured var bindings can be prevented and I think it’s useful. Lots of gotchas in js happen when closures accidentally mutate captured vars (or when captured environment mutate them).

                                                                                    Languages with multiple passing semantics such as PHP, which have by-value and by-reference passed function args, or Rust which have & and &mut, can have mutation prevention. In Rust you can see if object method does not mutate object if it has &self and not &mut self, for example. BTW, I written lots of PHP code and still don’t understand its semantics, it’s feels on the same level of complexity as Rust.

                                                                                  2. 1

                                                                                    Its not so much about whether you can have an immutable structure, it’s whether you think you can.

                                                                                    Before PHP’s const or define() supported e.g. constant arrays, you couldn’t assign them - it would error at compile time (which is effectively runtime for php).

                                                                                  3. 1

                                                                                    It’s not uncommon for things with undesirable qualities to emerge as the dominant entity in their domain. The flaws of JavaScript should not be assumed to correlate with its rate of adoption, whether or not they should.

                                                                                    1. 0

                                                                                      Do you laugh because despite all of this Javascript is arguably actuslly taking over (for whatever that means), while PHP, with its real consts, is slowly fading away?

                                                                                      1. -1

                                                                                        would this be the same javascript community that was just recently ass fucked in public because they needed a third party module to pad strings, or the one that needed a third party module to determine if a number is even?

                                                                                        I use php but I’m not attached to it. I also write shell regularly and I’ve used some Lua, a bit of java even. I’d like to try D soon.

                                                                                        Even then I’ll use php or shell or lua or whatever where it’s appropriate.

                                                                                        The javascript community has no such concept. That’s why you end up with ridiculous nodejs “alternatives” for things that could be achieved out of the box with a little shell on most *nix systems.

                                                                                    1. 1

                                                                                      If all variables are const except those that are reassigned, let becomes a strong signal to expect the reassignment. I don’t see a difference between assignments that “should” never change and assignments that “just happen to never change”. From the perspective of someone reading/debugging code, the question is simply “did the assignment change?” If I use const everywhere, this question can be quickly and confidantly answered. If I use let for assignments that don’t actually change, then I lose the certainty that let signals a reassignment somewhere further in the execution.

                                                                                      “Const isn’t useful because the assigned value is still mutable” is a confusion about the semantics of const. Mutability and side effects create many traps. Mutable assignment is one trap. Mutable values is a second trap. Strict use of const and let is an escape from the first trap. The author must look somewhere else for an escape from the second trap. In general, s/he might be better served by a compile-to-JavaScript language.

                                                                                      1. 7

                                                                                        I have a few things that I’ve been working on for the past 8 weeks:

                                                                                        • data visualization project
                                                                                        • ActivityPub implementation
                                                                                        • working through Haskell Programming from First Principles

                                                                                        I’m in a rut where I’ve lost conviction about all three of these projects. I’m enjoying Haskell Programming from First Principles the most but I’ve been demotivated lately by the thought that I should be focused on applying technology in useful ways more than learning new technologies. I don’t have any immediate or practical need to learn Haskell. I don’t expect to use it professionally. I just think the ideas are pretty interesting. But I can’t escape the feeling that there’s something more important I could/should be working on. So I’m in a rut where I have some things I could work on this week but little motivation to work on them, and I’m not certain how to resolve this stalemate.

                                                                                        1. 8

                                                                                          Would recommend to any developer who has a few months of mostly-free-time-ahead to dive deep into the Haskell world without regards to such concerns. Just a few months, then step back. Chances are high from numerous anecdotals including myself you’ll be a whole-new-developer in whatever “real-world languages” you come back to. Not in the ivory-tower over-abstracting sense either. Just in the sense of almost-deeply-instinctively circumventing the more subtle pitfalls of all non-purelyfunctional languages, and devising more-principled, less-convoluted designs. Maybe you won’t have that and maybe you’re already there anyhow — just saying, “chances are high”. In any event such time won’t be wasted and in your future real-world-work you will thank yourself for it, maybe even others (slightly less likely, nobody quantifies or detects infinite-numbers-of-troubles-avoided ;)

                                                                                          1. 1

                                                                                            I really appreciate the recommendation. I’m not totally new to the concepts in Haskell. For example, I know the basics of and am comfortable working with algebraic data types. I too have found that learning these concepts strengthens and clarifies my thinking in other areas of programming. That’s a big part of what I enjoy about Haskell and functional programming in general.

                                                                                          2. 2

                                                                                            FWIW, I don’t think I’ve ever really learned a language from a book. The examples / exercises usually feel too isolated and far-removed from the domains I work on.

                                                                                            I do have a ton of language books, but I use them more as references while I apply the language to some problem. That focuses what you need to know. Usually what I do is to find a bunch of 500-line code snippets in the language, and choose one to add a feature to.

                                                                                            I went through Real World OCaml a few years ago, and it was useful. But then I found an ocamlscheme project that I hacked on a bit, and that was a more useful learning experience. It wasn’t exactly practical, but I think it focused me on a few things rather than trying to ingest every concept in a book. There are still a bunch of things about OCaml I don’t know (and I think that is true for most people).

                                                                                            The Pareto rule generally applies – 20% of the language allows you to solve 80% of problems. There is usually a long tail of features for library authors (e.g. in C++).

                                                                                            1. 2

                                                                                              I agree and support the principle here, which I think is that abstractions are best learned through application and experience. I like focusing on the language first and then using the language to solve a non-trivial problem. I get overwhelmed if I try to learn the syntax and core concepts while also trying to think of how to best express myself in that language. But I would never consider the language learned until the second step was taken and I had used the language to complete a real-world task.

                                                                                          1. 2

                                                                                            If this method is more effective than others, I’d guess the mechanism of action abstracts to “solve a real world problem in the language to learn.” Open source is just a convenient source for real problems with the added benefit that your solution is code reviewed.

                                                                                            1. 3

                                                                                              It is the synthesis of “solves a real world problem”, “read code”, and “get someone who’s more experienced to review your code.”

                                                                                              1. 1

                                                                                                Some other benefits of open source over personal side projects (even though personal projects are a great way to learn a new concept/language) are:

                                                                                                • Your code is tested against a large test suite.
                                                                                                • Code quality guidelines help you pick up best practices specific to that language much faster than you would do usually do while working on your own projects.
                                                                                                • You get to interact with developers who have a lot of experience in that language which will also help you learn faster than a personal project where you code on your own isolated from other developers.

                                                                                                I agree with you that open source is just one of the ways of “solving a real-world problem” but for amateur developers, with little or no work experience it can prove beneficial and can get them up to speed with the best practices related to writing production quality code in a specific language(s).

                                                                                                1. 2

                                                                                                  Oh, and your code is run against lots of machines and configurations. Personal projects can reflect the quirks of your machine if they don’t get out into the world.

                                                                                              1. 1

                                                                                                It’s okay if the answer doesn’t mean a lot to you. It won’t map onto concrete coding intuitions very well. I don’t like this meme at all.

                                                                                                1. 4

                                                                                                  I recently read the chapter on the lambda calculus in Haskell Programming from First Principles, along with the papers suggested for further reading. It was a great surprise to find that a topic I assumed would be hard to access without a math background was plenty accessible when explained well. Thank you for that!

                                                                                                  What are your thoughts on the most effective way to explain monads? I thought @hwayne’s post https://hillelwayne.com/post/monad-tutorials/ was a good elucidation of the imperfection of all familiar monad explainers. I haven’t read the chapter on monads in your book, which might be the answer to my question.

                                                                                                  I think explanations like this SO answer are often regarded as unhelpful to beginners. But the most fruitful insights I have come from the learning I do in an attempt to understand statements like “a monad is just a monoid in the category of endofunctors”. The best intuitions I’ve in concrete applications of these topics have come from struggling to understand these concepts abstractly, in terms of algebraic law and not in terms of metaphor or patterns of use.

                                                                                                  1. 2

                                                                                                    What are your thoughts on the most effective way to explain monads?

                                                                                                    You already mentioned how I think people should learn Monad: Haskell Programming from First Principles.

                                                                                                    But more seriously, there’s no point explaining Monad to someone unless they’ve already learned enough Haskell to learn Monad in Haskell. The word-stuff and thought-stuff that Haskell equips you with gives you an automatically verified, mechanical way to work through exercises that will teach you Monad.

                                                                                                    1. 3

                                                                                                      I really have to agree with this. I was just reading “Real World Haskell” today (refreshing my Haskel for programming competitions), and it’s chapter on Monads was very clear, since the book had been building up to it, not by introducing the maths (that was in fact the last part of the chapter) but by showing it’s use, background (idea) and slowly sneaking up to the actual implementation.

                                                                                                      To do this properly, blog posts will rarely find the right words. It’s a longer processes, where at the end you realize that you’ve already understood it for a while, and all that was missing was the name.

                                                                                                1. 11

                                                                                                  This problem is largely solved by “Jump To” in an IDE (or fancy editor). This sort of thing is why I no longer do real work in languages without these niceties. I just don’t have the patience for it any more.

                                                                                                  1. 5

                                                                                                    Code reviews and online examples can suffer though - I have a very hard time reading unfamiliar Haskell and Agda code on Github where definitions aren’t either explicitly imported in an import list or given a qualified name. But perhaps that’s an argument for better online tooling…

                                                                                                    1. 2

                                                                                                      That’s a good point, although I agree that better tooling is probably the answer, particularly since fully-qualified imports still mean you’re stuck tracking down docs and such in code review with most of the existing tools.

                                                                                                      1. 1

                                                                                                        I have to admit, I fully agree with brendan here. Fully qualified imports really do increase readability to any new, or even old code.

                                                                                                        I don’t think better tooling is the best approach, I find explicit versus implicit generally explicit ends up being clearer.

                                                                                                        A possible middle ground is allow ONE unqualified import only as (if i remember right, only skimmed docs) purescript does. That would at least remove ambiguity as to where something could be coming from.

                                                                                                      2. 1

                                                                                                        Haskell’s Haddock supports hyperlinked source and so does Agda.

                                                                                                      3. 4

                                                                                                        you don’t even need that much; I find vim’s split-window feature is perfectly usable if I want to read the code where something is defined, or look at both the current code and the top of a file simultaneously. whereas on the flip side I know if no good way to eliminate the visual clutter caused by fully qualified names everywhere.

                                                                                                        1. 4

                                                                                                          You also can generate ctags and use them in vim ;)

                                                                                                          1. 1

                                                                                                            true :) I used to do that more often in my c++ days; somehow I lost the habit now that I’m doing python at work and ocaml at home, even though ctags would probably help with both of those.

                                                                                                          2. 3

                                                                                                            this doesn’t solve the “import all names” problem that you hit in languages like Python where some people do import * or you are importing something that was already re-exported from another location. You end up with busy work that an IDE could handle with a name lookup

                                                                                                            Though I agree that once you find the definition, split windows is a pretty nice way to operate

                                                                                                            1. 1

                                                                                                              I too find the result to be cluttered. But I also find new programming languages/syntaxes to be strange and chaotic in the same way. Once I use the language long enough, I am no longer overwhelmed. My hypothesis is that the eye will adapt to fully qualified names everywhere in the same way.

                                                                                                            2. 1

                                                                                                              I came here to say just this: with a sufficiently smart editor (vim, ide, or otherwise) this problem goes away almost entirely.

                                                                                                              That said, I think there are some arguments to be made for always-qualified imports

                                                                                                              1. 6

                                                                                                                I think it can be a cultural thing as well. I never enjoy typing datetime.datetime but don’t mind collections.namedtuple. itertools.ifilter is annoying though. Redundant words or information looks and reads bad.

                                                                                                                When the culture is to assume qualified imports, then the library will always be used to provide context, and that can be quite nice.

                                                                                                                When resolving a qualified name is the same syntax as a method call, that can look bad quickly. Python very much suffers from this problem. Think of Clojure stylebanespace syntax as an alternative.

                                                                                                              2. 1

                                                                                                                Does “Jump To” actually jump you to the import declaration or the function definition? I’ve never used an IDE. My guess is that an IDE would largely eliminate manual identification of the function’s origin. So that’s useful! But I’m not convinced that this would be faster than reading the module name inline in plain text. No keystroke or mouse click required to get the information. I guess the argument for using an IDE to solve this problem is something like the IDE places the information close at hand while also enabling a less verbose code style. That’s a reasonable argument. At some point the conversation becomes purely a debate about the pros and cons of IDEs. Then I would say that it’s nice to have code that doesn’t incur a dependency on a code editor.

                                                                                                                1. 2

                                                                                                                  You can jump to the declaration in most IDEs (provided there is support for the language). In many you can also view the documentation for a symbol inline, no need to go searching in most cases. I agree with you that this really just changes the debate to one about tooling. However, since many people (myself included) prefer the readability of unqualified imports, tooling support is important to at least think about. For example, I work in Dart a lot at work, the Dart community tends toward unqualified imports because, at least in part, I think, pretty much everyone who writes Dart code uses either an IDE or an editor plugin with IDE-like features.

                                                                                                              1. 5

                                                                                                                The file is 649 lines because large files are encouraged.

                                                                                                                A 649-line file is not a large file… ?

                                                                                                                1. 2

                                                                                                                  The same project has several files that are thousands of lines long. I took a shorter example so it wouldn’t seem hyperbolic. The point is that this file fills more than a single screen so checking the import declaration means jumping to a new context.

                                                                                                                  1. 1

                                                                                                                    Depending on the situation it might be. Though considering that I’ve seen a fair share of 1KLoc and 10KLoc files, that doesn’t really seem too large to me either.

                                                                                                                  1. -4

                                                                                                                    The language is called Go :)

                                                                                                                    1. 10

                                                                                                                      I have found it useful to use “golang” when doing google searches.

                                                                                                                      1. 13

                                                                                                                        There are two languages called Go as far as I can tell :-) I thought using Golang is nice way to differentiate.

                                                                                                                        1. 2

                                                                                                                          Rob disagrees :)

                                                                                                                          1. 9

                                                                                                                            You make a pedantic comment that ignores the common use of “Golang” to refer to the Go language. Your defense of this comment is the appeal to authority fallacy. None of this has been constructive, insightful, or even particularly correct.

                                                                                                                            1. 0

                                                                                                                              Your defense of this comment is the appeal to authority fallacy

                                                                                                                              Is Rob Pike not a trusted authority with a relevant opinion here?

                                                                                                                              1. 0

                                                                                                                                Rob Pike is an authority and his opinion is relevant. But if Rob Pike’s opinion is correct, it is not because he is Rob Pike. Thus, “because Rob Pike said so” is not a winning argument. The fallacy of the appeal to authority is not that authorities aren’t authorities. It’s just that what authorities say, like anything anyone says, must be proven.

                                                                                                                            2. 13

                                                                                                                              Rob is wrong.

                                                                                                                              1. 0

                                                                                                                                Yeah, some random internet commenter knows better what the name of the language is than its creator.

                                                                                                                                1. 6

                                                                                                                                  Creating something does not mean that one automatically has a good idea of what a good name, method or workflow is for other people.

                                                                                                                                  1. -3

                                                                                                                                    Creating something most certainly gives you the exclusive right of giving it a name, regardless of what someone else thinks about that name. Otherwise I’m just going to call you Martin Shkreli from now on.

                                                                                                                        1. -2

                                                                                                                          Here’s my issue: if you’re asking me for an estimate, you’re communicating that what I’m doing isn’t that important. If it were important, you’d get out of my way. A deadline is a resource limit; you’re saying, “This isn’t important enough to merit X, but if you can do it with <X, I guess you can go ahead”. If you ask me for an estimate, I have to guess your X (and slip under it if I want to continue the project, or exceed it if I want to do something else). If that seems self-serving or even dishonest, well let’s be honest about the dishonesty, at least here: estimates are bullshit anyway, so why not use the nonsense game for personal edge? Of course, if you’re the one being asked for an estimate, the system and odds are against you in nearly all ways, and you probably made some career-planning mistakes if you’re my age and still have to give estimates, but never mind that for now….

                                                                                                                          There are projects that are nice-to-have but not important and might be worth doing, but that aren’t worth very much and therefore should be given resource/time limits from on high. I just don’t want to work on those. If it’s not doing with an open deadline, then assign someone at a lower skill level, who can still learn something from low-grade work. This isn’t me being a prima donna; this is me being realistic and thinking about job security. If having it done cheaply is more important than having it done well, I can (and should be) replaced by someone else.

                                                                                                                          1. 3

                                                                                                                            Businesses regularly put resource limits on investments, I don’t see why software engineering salaries are exempt from this.

                                                                                                                            1. 0

                                                                                                                              I don’t see why software engineering salaries are exempt from this.

                                                                                                                              It might have something to do with the fact that the top 5% of us, at least, are smart enough that we ought to be calling the shots, rather than being pawns on someone else’s board.

                                                                                                                              1. 2

                                                                                                                                Unless you are literally on the board of a privately held company, you are pawns on someone else’s board. This isn’t hopeless, it’s just being honest with where actual final financial votes are cast.

                                                                                                                                How “smart” you are doesn’t mean you deserve to call any shots, as much as anyone who owns the company doesn’t deserve to either. Building relationships, managing expectations, cost analysis and collecting requirements are all part of making engineering estimates, and they are tools for you to exert influence over someone who has ownership/authority.

                                                                                                                            2. 2

                                                                                                                              What if all work is estimated? These inferences depend on selective estimation.

                                                                                                                              1. 1

                                                                                                                                I’ll disagree with you here a bit–I agree with your last paragraph’s approach, but I think you are leaving out a little bit.

                                                                                                                                It’s worth it to send overqualified engineers into certain projects exactly because they are more likely to know how to fix problems preemptively and because they are more likely to have a narrower distribution on the time taken to achieve the task. If you want something with a known problemspace done correctly and to a guaranteed standard and in a timely fashion, you shouldn’t send people who are still learning.

                                                                                                                                “This isn’t important enough to merit X, but if you can do it with <X, I guess you can go ahead”.

                                                                                                                                Unfortunately, this is a lot of business, right? Like, scheduling and organizing coverage and resources for projects often means that, say, a full rewrite would take too many engineers off of customer-facing work, but incremental cleanups are possible.

                                                                                                                                From the employee side, it is arbitrary, but there is at least a chance of method to the madness.