8 ms·
I wish there were even more of this sort of thing, even though I'm an anti-braces zealot - it's crazy to me that, here in 2024, code is still so tightly linked
by 12_throw_away 2y ago
I wish there were even more of this sort of thing, even though I'm an anti-braces zealot - it's crazy to me that, here in 2024, code is still so tightly linked to specific textual representations. Maybe there's an alternate reality where IDEs and development tooling got better and better post-smalltalk/lisp, instead of ... whatever we have now. Maybe we'd have editors and viewers where you could configure the syntax however you wanted. And sure, it would be persisted to disk in some canonical representation, maybe text, maybe a DB ... but you'd never need to worry about it, because all your tooling (VCS, diffs, refactoring tools, etc) would work with the AST, and you'd never need to worry about tabs or spaces ever again.
- rthnbgrredf 2y agoThanks to LLMs, we are quite close to achieving this. I can write code in Python (sometimes even plain english), and GPT can convert it to Go or even Haskell if I like. The conversion is accurate 95% of the time on the first attempt in my use cases, and I expect this to improve further with more powerful models in the near future.
- 12_throw_away 2y ago[flagged]
- rthnbgrredf 2y agoI think it is not so much surprising that large language models are particularly good at languages, including programming languages.
- randomtoast 2y agoI can confirm that it is a suitable use case for GPTs. I do GPT-assisted programming language design and experimentation. In some cases, GPT-4 can even generate a basic interpreter that allows me to test my new language. Here is an example of GPT's output for Python with braces that was generated after just spending 10 seconds for the prompt: def preprocess_braces(code: str) -> str: lines = code.split('\n') processed_lines = [] indent_level = 0 indent_str = ' ' # 4 spaces for indentation for line in lines: stripped_line = line.strip() # Check for opening brace if stripped_line.endswith('{'): processed_lines.append(indent_str * indent_level + stripped_line[:-1].strip() + ':') indent_level += 1 # Check for closing brace elif stripped_line == '}': indent_level -= 1 else: processed_lines.append(indent_str * indent_level + stripped_line) return '\n'.join(processed_lines) # Example usage: code_with_braces = """ def example_function() { if True { print("Hello, world!") } for i in range(5) { print(i) } } """ processed_code = preprocess_braces(code_with_braces) exec(processed_code) # This will execute the transformed Python code print("Processed Code:\n", processed_code)
- im3w1l 2y agoThis code is incorrect though, as it doesn't account for braces in strings and comments. There are other issues too, but that is the big one.
- AdieuToLogic 2y ago> This code is incorrect though, as it doesn't account for ... Isn't this the fundamental problem with code generated by a statistical text generation algorithm? In other words, "code" is short for encoding a solution. And to have a solution to encode is to understand the problem to solve. Without understanding, statistical code generation is little more than a popularity contest.
- roywiggins 2y agoThe model doesn't "understand" anything, but if you, the programmer, understands it well enough, that can be enough to direct it to find a solution. You can do a lot with ChatGPT or Claude if wrong code is easy to spot (which will obviously depend on what you're working on). If you can easily spot mistakes these things can often come up with a fix once you point it out. I've had some real success converting small-scale production C++ code into Python using Claude. Stuff that isn't really deep or complicated, but it's still faster and less annoying using an LLM to assist. I am sure there are large domains where it's crap, but for relatively simple stuff (CRUD logic, simple file parsing) it does remarkably well.
- AdieuToLogic 2y ago> The model doesn't "understand" anything, but if you, the programmer, understands it well enough, that can be enough to direct it to find a solution. This is exactly my point. Whether a programmer uses past experience exclusively to author source code or a statistical code generator (LLM) and then their learned ability is orthogonal to my original premise. Without understanding, statistical code generation is little more than a popularity contest.
- 2y ago
- lgas 2y agoYou can take it a step further, LLMs can already "execute" arbitrary non-existent languages, with non-existent data. Here are a couple of examples using a tool I wrote[1]: % echo "nums 1 10 | filter even | to_words | map uppercase" | refab imagine TWO FOUR SIX EIGHT TEN % echo "with file '/tmp/top-ten-most-populous-cities.txt' do; cities = read; cities.each { |city| (city.name, city.utc_offset) }" | refab imagine Tokyo, 9 Delhi, 5.5 Shanghai, 8 São Paulo, -3 Mumbai, 5.5 Mexico City, -6 Beijing, 8 Osaka, 9 Cairo, 2 New York, -5 For what it's worth, the tool isn't specialized for this, 'imagine' is just one of many prompts it can execute. Of course the execution is non deterministic and at the moment only works for simple things, but you can imagine as LLMs get more capable and more integrated with tools this will matter less and less. [1] https://github.com/lgastako/refab https://github.com/lgastako/refab
- hsbauauvhabzb 2y agoI hope we never work together. 95% accurate will cause problems that you won’t notice when you inevitably get lazy.
- dotancohen 2y agoThis is how I feel about cars that can drive themselves 99.9% of the time. The remaining 0.1%, the most difficult of corner cases, are to be handled by the human who has no experience driving even in good conditions.
- rthnbgrredf 2y agoI'm a strong advocate for writing tests first, maintaining a robust QA process, and ensuring all merge requests undergo peer review. Since I started using GPT-4 for coding, the quality of my merge requests has remained the same. The difference is that I can now produce about twice as many merge requests, as GPT-4 handles the boilerplate writing, Stack Overflow searches and helps to start get going in case of a mental blockade or missing idea.
- hsbauauvhabzb 2y agoBy what metric do you measure quality? Plenty of gpt users were dumping low qualify contributions prior to gpt, now their contributions are the same idiotic trash but appear more competent…
- digging 2y agoI largely agree, but I don't think the current experience is the right one. I recently started writing a game in Godot. I don't know GodotScript, and I've found I don't like it very much in trying to learn. I turned to aider.chat to see if I could describe the functions, data structures, and systems I wanted and have it write them. I also tried writing in a more familiar language (...one with braces...) and having it translate those files. It does pretty well, but it doesn't feel like software engineering. It's too hands-off and doesn't activate the same neurons. All the problem-solving and puzzle-solving is gone, and the successes are quite boring, and the failure modes are more irritating even if they're necessarily quicker to solve. It's a weird experience. I'm moving so, so much faster than I would have on my own, but I don't enjoy it. It feels like cheating - I'm not actually ashamed of what I'm doing but I also won't take credit for writing the code. However, what I'm getting at is this: If I could write the code in a syntax or even language that I prefer and have copilot or whatever translate it in near-real-time (without active prompting), that would be the best of both worlds. I'd still be a little sad at myself if I didn't learn the new language, but I also think this method would facilitate learning better than what I'm doing with aider (because I could see what my code turns into as I'm writing it, and learn that "translation").
- deleted 2y ago[deleted]
- TOGoS 2y agoThis is what Unison is supposed to do. As far as I know there is currently only one (Haskell-like) textual representation, but the program is stored in a binary representation of the AST, and once you've entered your code, it's all operations on that AST from then on, and adding different frontends should be not difficult.
- foolswisdom 2y agoWell, a few days ago there was a post about the Unison language, where code is stored in AST form and text is just a representation. https://news.ycombinator.com/item?id=40882133 https://news.ycombinator.com/item?id=40882133
- __MatrixMan__ 2y agoLast time I looked, [Unison code] -> [entry in the AST DB] was a one-way process. Adding a function means writing it (with whatever style you like) and seeing if what you wrote constitutes a new function or an existing one. You can't fluff db entries back up in to human friendly code. I don't see why it couldn't be done though, I think it just hasn't been a priority. Heck, you could have 100 different users collaborating in 100 different "languages", and so long as they serialized to the same AST and back, none of them would ever have to see the atrocious syntax which the other users prefer. Their editors and browsers could just render everything according to their users' preferences. Edit: it appears that Unison has an issue for this feature: https://github.com/unisonweb/unison/issues/499 https://github.com/unisonweb/unison/issues/499
- tkzed49 2y agoif they were truly represented by the same AST, I can't believe the differences between these "languages" would be anything more than swapping symbols out.
- __MatrixMan__ 2y agoTrue. Perhaps "styles" or "syntaxes" would be better. It's all that stuff we spend time building consensus around, but that doesn't affect program behavior. If our tools respected our style preferences on a user-by-user basis, we could drop the consensus requirement altogether.
- KMag 2y agoI've long dreamt of a system that compiles to native code, but stores a compressed SSA form (similar to SafeTSA or LLVM bitcode) in the binary for efficient runtime re-optimization based on profiling, somewhat similar to current Android Runtimes. One could then have several levels of debugging symbols, one that gives names to local variables represented by CFG nodes, and another that adds a compressed diff between some standardized decompiler output and the original source. You could then decompile to some alternative syntax, but you'd lose any idiosyncratic formatting represented by the compressed diff.
- hsbauauvhabzb 2y agoFirst we gotta solve the tabs/spaces dilemma, maybe then we can start to tackle the rest. Edit: I do agree and find your AST suggestion profound though!
- moonlion_eth 2y agoThere are tabs people and there are infidels
- pantulis 2y agoI was ready to throw some vitriol into your heretical comment and then I remembered I am also a tab person. Nothing to see here, sorry!
- hsbauauvhabzb 2y agoI mean my original comment was highlighting that it’s unsolved and it instantly started infighting so I think my point has been proven
- layer8 2y agoPeople should recognize that tabs vs. spaces is more a question of editing (e.g.: What happens when you press Backspace behind an indentation? Does the caret move at uniform speed on key repeat or does it suddenly jump in places?) than of stored representation. You could even have an editor/viewer that lets you choose the display-width of spaces at the start of lines.
- hsbauauvhabzb 2y agoDo tab users not realise they could configure their editor to auto-indent and delete multiple characters so they could move to the most superior spaces format?
- layer8 2y agoI don’t know of an editor who can fully emulate Tab behavior using a spaces representation (and vice versa), but it would certainly be possible.
- tkuraku 2y agoI think having a single syntax is the best way. I don't want to have to look at python and have to parse spaces, curly braces, square braces, etc. It all being standard is really helpful. A standard Autoformatter like black or gofmt even though I might might not choose all the options, the uniformity is super valuable.
- VirusNewbie 2y ago> I don't want to have to look at python and have to parse spaces, curly braces, square braces, etc. But if the syntax was separate from the underlying representation, couldn't you just have your editor open it the way you want?
- tkuraku 2y agoThat is true. That seems like a lot of complexity though.
- sverhagen 2y agoThis may be controversial, but I find 2-character indented Javascript, coming from my 4-character indented Java, for the projects I work on, as much of a shock as moving between braces and Python. Particularly if it has been subjected to an opinionated formatter that just doesn't match my personal style. Completely unreadable, I mumble under my breath. And then my eyes adjust to it for a bit, and after an... hour? (maybe) of coding in the (ahum) "hostile" style, it's familiar (again) and we're on our way.
- dotancohen 2y agoThis is why I prefer tabs for indentation. I get to see 4 spaces, the blue haired frontend kid gets to see 2 spaces, and Linus gets to see 8. Everybody's happy.
- raffraffraff 2y ago8?? His neck must be sore.
- quasarj 2y agoYou just described a literal nightmare D:
- griftrejection 2y agoCode is linked to textual representations because code... is text? The entire point is that there are algorithms to go from "print()" to something that actually makes the computer work. How else could it even possibly work? I think we don't have any sort of flexible AST sort of thing because they're mostly not necessary. The hard problems of programming don't usually have much to do with syntax. And if you're going to downvote, kindly explain why, thanks. I just want to know exactly how this thing is supposed to work...
- rgovostes 2y agoThe parent’s post describes how it could work. I may recall incorrectly but AppleScript may be an example: some file formats are serialized ASTs. The editor displays it as textual code. A downside of this is that you can’t save a syntactically invalid file.
- josefx 2y agoYou could always have an AST node to encapsulate the invalid code. Of course any affected code would be stuck in the source format it was written in until it was fixed.
- RHSeeger 2y ago> code... is text There are visual programming languages that chain together blocks, instead of raw text. > The hard problems of programming don't usually have much to do with syntax. I guess it depends on how you define hard. You are clearly talking about "a singular issue that needs to be solved", which really only effects a single developer / team and, to a lesser extent, those that use that solution. But if you consider something like syntax, you're now talking about something that much a much smaller impact _per developer_, but has that impact on _every_ developer. The syntax issue may have a much larger impact overall.
- eiffel31 2y agoCode is as much Text as Vector graphics is Text. Sure it's an intuitive way of representing your data. Is it the most appropriate though? See an example [0] about using Projectional Editing in order to use mathematical notations for formulas. [0]: http://voelter.de/data/pub/gemoc2014-voelterLisson-MPSNotations.pdf http://voelter.de/data/pub/gemoc2014-voelterLisson-MPSNotati...
- smsm42 2y agoNon-human-readable primary representation may be not the best idea though. Would create a lot of friction when trying to process the data. Text is largely simple and obvious (yes I know there are complications but in 99% of cases you can ignore them without too much trouble) but DBs and ASTs are not. People read texts, but they can't read ASTs, at least not without assistance. So it'd be hard to use.
- skissane 2y ago> Non-human-readable primary representation may be not the best idea though. What if the AST is persisted as S-expressions, but then you have a different syntax to edit it? Algol-ish, Pascal-ish, C-ish, Python-ish: choose your poison (or even support multiple poisons and let the developer pick the one they prefer?) This was actually the original plan with Lisp. Lisp was originally supposed to have two syntaxes, S-expressions and M-expressions, with M-expressions being Algol-like. However, the implementation of M-expressions was delayed, and people got so used to using S-expressions directly, they decided M-expressions were unnecessary and they were never implemented in mainstream Lisp. They were implemented in the Lisp 2 project, but that ended up being an evolutionary dead-end; various attempts at the idea have happened since but none of them really took off. Lisp purists will argue M-expressions are unnecessary and S-expressions are all you need. However, S-expressions can make the language more foreboding to complete beginners, and even among experienced programmers, a decent percentage find them seriously off-putting. Maybe if the M-expression idea had been pursued more seriously, Lisp might be more popular today.
- lispm 2y ago> Lisp purists will argue M-expressions are unnecessary and S-expressions are all you need. I would argue that S-Expressions turned out to be extremely practical for developing Lisp software. A layer with different syntax makes it more complex to use. > Maybe if the M-expression idea had been pursued more seriously, Lisp might be more popular today. Maybe, maybe not. People have discussed it endlessly, but there is no conclusion. Currently some people in the Racket community try to make Racket more "popular" (widely used, ...) by providing a new syntax.
- signaru 2y agoMaybe no longer true today, but with the right tools, C# and VB.NET used to be auto translatable from each other and IL can be decompiled to either.
- hermitdev 2y agoIt was only ever true for "clr safe" code, or a subset of C#. In particular, since VB.NET didn't/doesn't have unsigned types, not all C# could be expressed in VB.NET, even after decompiling from IL. (Not sure what happens if you try and decompile to VB.NET code that uses unsigned, for example).
- Varriount 2y agoI can understand braces (to an extent...). What really confuses me are new languages that still require semicolons at the end of expressions/statements.
- IcyWindows 2y agoWhy is that so much more different from requiring '\n' instead of ';'?
- gavindean90 2y agoMaybe I like the ‘\n’ for me and the ‘;’ for the compiler.
- xigoi 2y agoThere should be only one source of truth.
- sodapopcan 2y agoBecause when reading as a human you're typing `\n` anyway which fits in with the whole "Can't the computer just figure out what I'm seeing?" thing. While it's technically correct (the best kind of correct) that it's '\n' vs ';', in practice it's really ';' vs ';\n'. I can only speak to my personal experience but seeing two expression on one line is so rare that I can't even think of an example of the last time I saw it.
- masklinn 2y agoThe problem is not two expressions on one line, it’s one expression on two lines. e.g. foo .bar() now you need to either add syntax to specify that you’re “continuing” (python), play tricks for the parser (Go), or have unreliable magic biting you in the ass half the time (javascript).
- deleted 2y ago[deleted]
- heresie-dabord 2y ago> you could configure the syntax however you wanted. And sure, it would be persisted to disk in some canonical representation, maybe text, maybe a DB ... but you'd never need to worry about it, because all your tooling (VCS, diffs, refactoring tools, etc) would work with the AST, and you'd never need to worry about tabs or spaces ever again. You are describing an entire industry of IDE Smell with an IDE monoculture.
- crabbone 2y agoI believe, this was an idea in ALGOL, not sure which iteration. I think, the reason it was never implemented was that more translation = more complicated debugging. It also means that programmers have a more distorted and incomplete model of the program they are writing, i.e. more bugs. NB. Lisp, as originally envisioned by McCarthy, had one more translation layer (the translated version had square brackets instead of the parenthesis), but it didn't take off for, basically, the same reason. So... while I understand the benefits you see from doing what you suggest, I think that at the same time the downside makes this not worth pursuing.
- bsza 2y agoSo much opportunity for anti-competitive behaviour. The "canonical representation" of C# could just be a memory dump of Visual Studio. Your code is held hostage forever. Everything you create belongs to Microsoft. You have to drink a verification can to keep using your IDE. Basically Unity/Adobe/etc, but for code. No thanks.
- neonsunset 2y agohttps://github.com/dotnet/dotnet https://github.com/dotnet/dotnet there, the entire source code of runtime, sdk, roslyn, etc. And you will have easier time getting your changes merged into dotnet/runtime than into Python.
- bsza 2y agoYou do realize I'm talking about the OP's alternative reality, not ours?
- neonsunset 2y agoIt's HN, so the sarcasm above is often expressed seriously, as unfortunate as it is. You are right, of course.
- eiffel31 2y agoYou can (sort of) do all of that with the Eclipse Modeling Framework[0]. Your AST is what EMF calls a "model". By default the "backend" and ecosystem surrounding EMF is skewed towards Java for historical reasons, but there have been some prototypes with other languages as well. You can serialize your AST in any way you like, although by default it relies on XMI files. You can implement your own textual concrete syntax, or rely on a database. The EMF ecosystem has tools for implementing textual or "graphical" concrete syntaxes. You can combine them (e.g. usually a specific subset of your AST gets edited in a certain way that's best for your targetted end users). The ecosystem also has tools for performing comparisons and plugging them into your editing means. Of course all of this tooling requires a lot more work than an LSP server. [0]: https://eclipse.dev/modeling/emf/ https://eclipse.dev/modeling/emf/
- phaedrus 2y agoI like to draw the comparison that in an alternate universe where the ASCII .txt file format had simply included a color byte with every letter byte, we'd now be having coding format guidelines that also go into great detail prescribing manual syntax highlighting. The fact we don't and avoided endless bike shedding over syntax highlighting, instead leaving it to automatic tools and the presentation layer not the code itself, is purely an historical accident. Well, what does that say about other code formatting details which programmers currently do waste time manually doing and worrying about?
- pseudosavant 2y agoI had never considered the bikeshedding that would occur if there was a color byte… We struggle with spaces versus tabs, how many spaces, braces (or not), semi-colon (or not). It would definitely be the norm that there were languages that were dark or light mode, and both sides would be convinced they were right.
- mock-possum 2y agoThat one person who absolutely insists that enums are blue and everyone who can’t see it is a failure of a programmer
- philipov 2y agoI had never considered that, but you're absolutely right. I would totally be the sort of person to manually idiosyncratically syntax highlight my code if it were feasible. I'm sure glad I don't feel compelled to do that...
- masklinn 2y agoAn other option is to have the color be semantically significant in which case you can't idiosyncratically syntax highlight. That's what colorForth does. It's weird.
- zzo38computer 2y agoSome programming languages such as ColorForth require colours in order to work, that the meaning of a word depends on what colour it is written with.
- Vegenoid 2y agoSeems like the biggest downside would be that sharing code becomes much harder. Currently it is easy to share code in as small of a portion as you'd like. If the canonical representation is an AST, it opens up a lot of problems around sharing pieces of a program. This seems like a very substantial downside. Even simply "sharing" within your own systems, like copying blocks into notes or another program, would be a lot harder. Maybe I'm not knowledgeable enough here and this wouldn't be as thorny as it seems.
- hombre_fatal 2y agoAlso, I really don't want to have to load any and all code into a local editor just to view it and reason about it.
- arp242 2y agoThere's always someone who mentions this, and it just doesn't work. Do you group things like: do_stuff() more_stuff() other_stuff() moar_function() Or: do_stuff() more_stuff() other_stuff() moar_function() Or: do_stuff() more_stuff() other_stuff() moar_function() Grouping code by a single blank line can make a big difference. This is a bit of a silly example, but there's tons of not-so-silly examples. You can't really represent that in an AST. Line length is another. infinite line length doesn't work as screens aren't infinitely long. Automatic wrapping doesn't work because you want to break at specific points. An example is something like: window = XCreateWindow(display, XRootWindow(display, screen), center_x, center_y, size, size, 4, // border width vinfo.depth, CopyFromParent, // class vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel | CWOverrideRedirect, &window_attr); Cramming as much as possible on as few lines as possible is just not going to work well. There's tons of cases. That's why no one does it. Because it just won't work. Everyone will hate it.
- otteromkram 2y agoI agree about horizontal space adding to readability and I use that method fairly often. That said, if you use classes, descriptive names, and appropriate comments, it won't matter how you group because your code will be self explanatory. Finally, with today's wide-screen monitors on desktop, line length is less of a worry. Problem only arises when reading code on mobile devices. The last workplace I was at had a soft wrap around 80 characters, but we upped that to 100 when functions and methods became almost vertical.
- arp242 2y agoYou want to wrap in logical locations at times. That's my point. To repeat: cramming as much as possible on as few lines as possible is just not going to work well. Wrapping at column 80 vs 100 or whatever has nothing to do with that. That XCreateWindow() would be: window = XCreateWindow(display, XRootWindow(display, screen), center_x, center_y, size, size, 4, vinfo.depth, CopyFromParent, vinfo.visual, CWColormap|CWBorderPixel|CWBackPixel| CWOverrideRedirect, &window_attr); And that's just not better. It's much much worse. Only a human can judge where it makes sense to break things (or not break things). Completely forbidding "paragraphs" would be atrocious. Almost everyone will hate it. Just like everyone hates walls of text in comments. And in the end a huge amount of complexity is added throughout the entire stack (from editors to grep to sed to code hosting) for very marginal gain with significant trade-offs.
- LeFantome 2y agoIn the .NET universe, you can mechanically convert between C# and VisualBasic. This is more or less done by going through CIL ( Common Intermediate Language - .NET assembly essentially ). So, it is more or less what you are saying. .NET decompilers are common. I have built a few toy languages and compilers on .NET. For one of them, I could decompile CIL into my language. So, I could view .NET libraries from other sources in my language. I think this is essentially the same idea you are proposing. It only works if the languages are similar though. Going between F# and C# does not always work as well for example.
- harimau777 2y agoThat actually exists for C. It's pretty neat. https://en.wikipedia.org/wiki/Indent_(Unix) https://en.wikipedia.org/wiki/Indent_(Unix)
- turndown 2y agoPrograms are tightly coupled to textual representations because a compiler is a textual representation transformer. If you deviate from the accepted textual form then the compiler is generally clueless to do anything - that is, it can’t read your intent.