[HN Gopher] Python with Braces
___________________________________________________________________
Python with Braces
Author : punnerud
Score : 65 points
Date : 2024-07-03 14:05 UTC (4 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| teddyh wrote:
| >>> from __future__ import braces File "<stdin>", line 1
| SyntaxError: not a chance >>>
| kibwen wrote:
| Joke's on Python, it already supports braces:
| def foo(): #{ if True: #{ print("The
| future is now, old man") #} #}
| gedy wrote:
| Ha cool, you could probably make a font with ligatures to
| hide the # too
| kazinator wrote:
| More than that, you could write a tool which checks the
| consistency of your indentation against your #{ and #}.
|
| This has advantages over using a generation tool that has
| to strip away braces to produce valid Python.
| giancarlostoro wrote:
| I was going to complain that they need to be on separate
| lines, and then I realized it would work that way, though
| PEP-8 and Pycharm might complain.
| mort96 wrote:
| Honestly, this looks more readable than Python. Noticing whether
| something is 3 or 4 levels less indented than something else is
| really really hard. Noticing whether there are 3 or 4 braces is
| easy.
| jjallen wrote:
| Why not use your editor to do this? I would never expend mental
| energy doing something this trivial in 2024.
| teddyh wrote:
| Yes. A quick search yielded:
| <https://github.com/DarthFennec/highlight-indent-guides>
| mort96 wrote:
| Use my editor to do .. what exactly?
| rented_mule wrote:
| Use what are often called "indentation guides". Here's an
| extreme form of them from the blockman extension for
| vscode: https://raw.githubusercontent.com/leodevbro/vscode-
| blockman/...
| mort96 wrote:
| 1) that looks incredibly cluttered (yes, even compared to
| braces), and 2) it doesn't help a whole lot when reading
| code in any context what so ever which is outside of my
| preferred editor (including in github/gitlab merge
| requests or 'git diff' locally)
| rented_mule wrote:
| For me, what is visual clutter is all about what I'm used
| to. After a short period of adaptation, I found
| indentation guides disappeared when I was looking for
| them. You can also choose your styling. As I mentioned
| above, that was an extreme example. Here's a style that
| adds very little clutter (mine look a lot like this):
| https://i.sstatic.net/nxPrP.png
|
| Also in the spirit of modern tooling, VSCode has had the
| ability to navigate GitHub Pull Requests, with all the
| normal code editing tooling, since 2018. I'd be surprised
| if it's alone in that ability in 2024. The same is
| possible with Gitlab Merge Requests using Gitlab's own
| extension. I can also use VSCode to remotely edit on
| almost any Linux/Mac/Windows machine that I can ssh into,
| or inside Docker containers.
| xigoi wrote:
| Unlike braces, indent guides don't take up vertical
| space, so it's much less cluttered.
| mixmastamyk wrote:
| Indentation guides have been a thing in editors for about
| thirty? years. Geany supports them for example. Turn them
| on and never mistake a level again.
|
| I also turn on visible whitespace but make the color very
| subtle in the syntax highlighting section. Makes
| inconsistencies jump off the screen. Other little features
| like deleting trailing whitespace are your friend.
| mort96 wrote:
| Oh I'll just call Microsoft and ask them to install an
| indentation guides plug-in to the GitHub merge request
| diff view, one sec
| mixmastamyk wrote:
| Everything outside of notepad already supports it--that
| was the point, dumbass.
|
| Diffs are not an area where it (or braces) are useful
| anyway, due to the merge of the two views.
| mort96 wrote:
| How do I enable that feature in the GitHub merge request
| diff view?
| mixmastamyk wrote:
| I just explained why that question is nonsensical. What
| do you hope to achieve by repeating it?
| mort96 wrote:
| You said:
|
| > Everything outside of notepad already supports it--that
| was the point, dumbass.
|
| As a response to me pointing out that it's not supported
| in the GitHub diff view. That response is nonsensical
| unless you meant to say that it's supported in the GitHub
| diff view.
| mixmastamyk wrote:
| No one is using block markers or indentation guides in a
| diff view because that doesn't make sense. The two+ views
| would conflict with each other, so vast majority of such
| tools don't even try to understand blocks. (difftastic
| however, on the terminal tries.)
|
| If a diff is particularly complex (it shouldn't but
| assuming) you'll need to look at the destination in full
| and confirm tests etc have passed.
|
| Any non-theoretical issues you'd like to discuss?
| mort96 wrote:
| Let me try again.
|
| You said:
|
| > Everything outside of notepad already supports it--that
| was the point, dumbass.
|
| As a response to me pointing out that it's not supported
| in the GitHub diff view. That response is nonsensical
| unless you meant to say that it's supported in the GitHub
| diff view
| mixmastamyk wrote:
| It's clear that my original statement referred to editors
| of source code. You then moved the goal posts to "merge
| diff" views on a website.
|
| Despite that, I explained this didn't make sense, diffs
| being line-based and not block-based and all that.
|
| That's two fundamental problems with your line of
| argument. This is my last reply.
| mort96 wrote:
| Let me try again.
|
| You said:
|
| > Everything outside of notepad already supports it--that
| was the point, dumbass.
|
| As a response to me pointing out that it's not supported
| in the GitHub diff view. That response is nonsensical
| unless you meant to say that it's supported in the GitHub
| diff view
| necovek wrote:
| Ignoring the tone of the other poster, the point they are
| making is that there is no clear value for indentation
| markers in a (unified) diff view, which is based around
| lines being removed and added.
|
| Similarly, you might not even see braces for the
| corresponding block, so the braces-vs-spaces is not
| really a win for "braces".
|
| However, I am guessing you are mostly using side-by-side
| diff view (as opposed to unified diff view), which might
| have some value to indicate indentation change for a
| bigger chunk of the code. But again, if you are not
| seeing where the block starts or ends with braces in the
| diff block, why is whitespace in any way "worse"?
| jjallen wrote:
| To reformat your code for you. Quick two strokes should do
| it. I use Jetbrains and it's select all -> alt ctrl L I
| think. Massive timesaver. Anything a computer can do to
| help coders good IDEs can do in the blink of an eye.
| Myrmornis wrote:
| I hope you don't have to do that very often. Occasionally,
| sure, but a lot of functions that have an indentation drop of 3
| or 4 levels would be better refactored.
| mort96 wrote:
| I'll remember to tell that to everybody whose code I could
| ever have to read in the future but I don't think it'll have
| much effect, we're talking at thousands of people I'm
| guessing and I don't know most of them
| necovek wrote:
| How much Python have you ever written or reviewed? With only a
| bit of experience, I am sure you'd have no trouble doing that
| if the Python code is not using 2-space indentation.
|
| It certainly becomes a problem if you are looking at a 100+
| line method/function, but with Python being as expressive as it
| is, a 100+ line method/function is a problem unto itself.
|
| Otherwise, I've never had any issues with it -- even with
| languages other than Python, I mostly rely on white space and
| alignment to understand the block boundaries, only resorting to
| reviewing the braces carefully when something is amiss.
| adolph wrote:
| I had to do a quick check if python do have teeth and thus use
| braces. My initial thought was that they do not as the most
| prominent teeth on snakes are fangs and python are not venomous.
| They do have teeth for holding their pray as they constrict it.
|
| _Pythons use their sharp, backward-curving teeth, four rows in
| the upper jaw, two in the lower, to grasp prey which is then
| killed by constriction; after an animal has been grasped to
| restrain it, the python quickly wraps a number of coils around
| it. Death occurs primarily by cardiac arrest._
|
| https://en.wikipedia.org/wiki/Pythonidae
| m463 wrote:
| Do they have colons, or semi-colons?
|
| They seem to have semi-lungs, with a right lung and a vestigial
| left lung
|
| https://upload.wikimedia.org/wikipedia/commons/4/4d/Snake-an...
| Fraterkes wrote:
| Is significant whitespace good or bad? Maybe 3/7/2024 is finally
| the day we get to the bottom of this.
| efilife wrote:
| Bad. Further discussion below
| kazinator wrote:
| Below here. It has been determined that discussion is not
| required.
| enricotr wrote:
| Ahahahahahahaah
| 8xeh wrote:
| Without significant whitespace, you'd need at least 5
| more comments consisting solely of "}" for this reply
| chain to be syntactically correct.
| gary_0 wrote:
| Braces, maybe. But I've always felt that semicolons at the end of
| lines were just noise. I can tell it's the end of the line
| because it's the end of the line. The few cases of ambiguity that
| happen can be solved by common sense (in the programmer or in the
| parser).
| ilyagr wrote:
| This is what golang does.
|
| https://go.dev/doc/effective_go#semicolons
| xpl wrote:
| Also, JavaScript.
| gary_0 wrote:
| And Kotlin and Swift.
| xigoi wrote:
| Except JavaScript does it wrong.
| trealira wrote:
| What makes Go's semicolon insertion algorithm different
| from JavaScript's? They seem similar to me. Isn't it just
| that the Go compiler requires very strict formatting,
| which saves you from getting bitten by errors due to
| unexpected semicolons?
| xigoi wrote:
| The following (contrived) JavaScript code does not work:
| let x = 5 (function() { console.log(x) })()
|
| The equivalent Go code works: package
| main import "fmt" func main() { x :=
| 5 (func() { fmt.Printf("%d", x) })() }
| trealira wrote:
| Thanks, that's a good case.
|
| Actually, the JavaScript semicolon insertion algorithm
| [0] seems more complex than I had remembered. I had
| thought of them as variations on the semicolon insertion
| in BCPL, but it seems like that's an oversimplification.
|
| For reference, these are the BCPL rules:
|
| _The canonical symbol SEMICOLON is inserted between
| pairs of items if they appeared on different lines and if
| the first was from the set of items which may end a
| command or definition, namely:_ BREAK
| RETURN FINISH REPEAT SKET RKET SECTKET NAME
| STRINGCONST NUMBER TRUE FALSE
|
| _and the second is from the set of items which may start:
| a command, namely:_ TEST FOR IF UNLESS
| UNTIL WHILE GOTO RESULTIS CASE DEFAULT BREAK
| RETURN FINISH SECTBRA RBRA VALOF LV RV NAME
|
| ...
|
| _( ) [ ] SS SS are used to denote RBRA RKET SBRA SKET
| SECTBRA and SECTKET._
|
| [0]: https://developer.mozilla.org/en-
| US/docs/Web/JavaScript/Refe...
| kazinator wrote:
| Bourne and POSIX shell: for x in *.txt; do
| echo $x; done for x in *.txt do
| echo $x done
| trealira wrote:
| Haskell also inserts semicolons, but it has a different rule,
| which I think is a bit interesting.
|
| If the current line starts on the same line that the previous
| expression started on, then a semicolon is inserted at the
| beginning of the current line. There are also some messy
| rules about opening and closing braces being inserted.
|
| So, this: do expr1 expr2 do
| expr3 expr4
|
| Ends up being parsed as though it were written like this:
| do { expr1 ; expr2 do { expr3 ;
| expr4 } }
|
| If the next line is indented, it's just taken as a
| continuation of the previous line's expression, so nothing
| needs to happen.
|
| [0]: https://amelia.how/posts/parsing-layout.html
| nomel wrote:
| Semicolons are already supported in Python, for the cases where
| it might be needed (one liners on the command line), just not
| required. import sys; print(sys.executable)
| x = 5; # this is fine
| darby_nine wrote:
| > But I've always felt that semicolons at the end of lines were
| just noise.
|
| I felt this way until I engaged in code with very horizontal
| coding styles. Semicolons make it extremely easy to visually
| break up sequential statements from expressions consuming
| multiple lines.
| gary_0 wrote:
| > code with very horizontal coding styles
|
| I'm not sure what you mean. Could you give an example?
| darby_nine wrote:
| Literally just code with long lines. You run into this
| particularly with monadic stuff like LINQ queries.
| a3w wrote:
| First of april is not now. So I will seriously discuss the idea:
|
| IMHO, some level of linting should be required. I would often
| have to reject lengthy and excellent pull requests (PRs), just
| because autoformat was not pressed and three instead of four
| whitespaces are in kotlin code. That annoys everyone. Python does
| that right, code won't compile with the three version whitespace,
| which is easily spotted before the PR.
| giancarlostoro wrote:
| In Visual Studio I turn on the feature to see whitespaces and
| non visible characters, just because every now and then, for
| some ungodly reason, someone in the project, somewhere, in
| every C# project I've ever worked on, will somehow open the
| file differently (seriously wtf? we all use Visual Studio!) and
| goof up a file somewhere, or there's people who instead of
| hitting tab, will manually insert spaces in a way that doesn't
| match Visual Studio's own format.
| teddyh wrote:
| The documentation notes that reserving braces for blocks makes it
| very ugly to deal with dict literals, but it't also terrible for
| sets, set comprehensions, and dict comprehensions. You'd think
| they'd choose some other characters than braces in order to avoid
| this. I seem to recall that RPL used << and >> for program
| blocks.
| mwkaufma wrote:
| Why are braces-for-both-blocks-and-literals/etc a deal breaker
| here, but not in JS?
| throwitaway1123 wrote:
| Using braces in an arrow function that returns an object
| literal actually is ambiguous in JS, which is why you have to
| wrap it in parentheses, e.g.: const foo = ()
| => ({foo: 'bar'})
|
| If you omit the parentheses it gets interpreted as a block
| with a label and a string literal: const baz
| = () => {baz: 'bar'}
|
| https://astexplorer.net/#/gist/9a86e0b61fda312dce2ea9d10d37f.
| ..
| wfleming wrote:
| Probably because that makes parsing much more complicated,
| and this being a half-joking hobbyist project they didn't
| want to increase scope that much.
| jerf wrote:
| Because bython is basically a glorified regular expression
| search and replace: https://github.com/mathialo/bython/blob/m
| aster/bython/parser...
|
| Rather than a real parser. A real parser knows about the
| context it is in, and as long as the grammar is unambiguous
| about some character, it can be reused in as many distinct
| parser constructions as you like. A pure regex-based approach
| to a first approximation can not.
|
| Whether or not it _absolutely_ can or can 't, without
| "approximation" and with regard to the exact re library in
| Python, would be something you'd have to work out through
| tedious effort. Regexes with backtracking can do a lot more
| than mathematical regexes, as well as all the other
| elaborations you could use. But even if Python's re _can_ do
| it, you will be better off with a real parser.
|
| The "correct" solution, since by design Python and Bython
| share the same AST, is to take some existing code that can
| parse and re-emit Python code without changing it, tweak the
| incoming grammar to use braces instead, then emit the AST
| back out as Python. Then you wouldn't have this problem, or
| the problem with comments referenced in the source code (line
| 109 of the file I linked, just up a bit), or any of the
| probably other many little issues that would arise on real
| code if you tried to put this in real use. The only slight
| complication I can see is there may be a slight issue with
| comments around the braces. I'm not sure, and I'm not going
| to sit here & work it out fully for an HN post.
|
| Also, this is not a criticism of Bython. The author can do as
| they please with it. If nothing else you can always label
| this a prototype. Prototyping is good, right? Anyone who was
| rushing to slam this into production is just gonna learn a
| real valuable lesson worth its weight in gold, and not
| Bython's fault.
| sgt101 wrote:
| I don't like whitespace compulsion but I can live with it.
|
| self.onandonandon is a real pain along with copy.deepcopy
| AcerbicZero wrote:
| Whitespace is def wrong, but I'm not sure this actually makes
| things much better....still pretty awesome idea!
| hoosieree wrote:
| mascot: a python, with braces
| IshKebab wrote:
| Of all the things to hate about Python, this seems like the
| least. The indentation definitely _looks_ nicer. I 'd say the
| only real disadvantages it has are a) you are definitely
| restricted to statement-based constructs; no inline function
| definitions etc., and b) pasting stuff into the REPL is a mess.
|
| They could fix the latter, but the REPL is Python tooling so it
| is required to be awful.
| xigoi wrote:
| The statement thing could also be fixed. CoffeeScript, for
| example, is indentation-based and supports multiline
| expressions.
| IshKebab wrote:
| I had a skim of it but honestly it looks like it just gets
| really confusing. Like you have to spend time just mentally
| parsing the code. Not really what I want.
|
| Similar to OCaml which is very light on punctuation - code
| just ends up like a sequence of words, with an occasional
| comma and it's quite mentally taxing to figure out where the
| functions and parameters are.
| 12_throw_away wrote:
| 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 wrote:
| Thanks 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.
| randomtoast wrote:
| I 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 wrote:
| This 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.
| TOGoS wrote:
| This 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.
| gabrielsroka wrote:
| I found this here years ago: Python With Kurly braces.
|
| https://github.com/umlet/pwk
| glimmung wrote:
| I'm glad this exists for those who want it, but for me the added
| noise / cognitive load of all those braces is painful.
| pasc1878 wrote:
| For another way of removing indentation needed for structure.
|
| Make python a lisp - indentation is just the number of brackets.
|
| Hy - http://hylang.org
| darby_nine wrote:
| I don't understand why we don't make the aesthetic aspects of
| syntax (e.g. block delimitation) to be a feature of the editor
| rather than the source of truth for the code. For all unix
| profited from text I think we have the tooling necessary to move
| our storage and editors beyond it, and it's been obvious the
| entire time it comes with non-trivial liability converting to and
| from more reliably structured representations.
| williamdclt wrote:
| I think it boils down to "text is good _enough_" (80% of the
| value, 10% of the complexity if even that), and it's a format
| that's incredibly interoperable. You can use tools that aren't
| just language agnostic, but are not even programming-specific:
| notepads, grep, git, sed...
| islandert wrote:
| Would the JVM ecosystem almost be a working example of this?
| Since there are a variety of languages with editor integration
| that all compile down to the same byte code, it feels pretty
| close to what you're describing.
| kriiuuu wrote:
| Unison would fit here
| necovek wrote:
| This is a great discussion with many a differing point of view.
|
| To some, significant indentation is better.
|
| Others -- too used to braces -- miss them dearly in Python.
|
| Next ones, vie for the non-text source code, something to get us
| past these discussions altogether (editors working on .pyc files
| directly?).
|
| For programs to be maintained, they need to be read, understood
| and improved. One--often undervalued--skill in programming is to
| write beautiful code, because that is more art than craft. And
| unfortunately, tools like Black prohibit the true artists from
| expressing themselves clearly with code formatting too. And to
| those, white-space or braces matters on a different level, and
| everything else is attempting to make up excuses for why one is
| better than other.
|
| And while conceptual operations we do on the code seem simple on
| the surface, devising an editing tool that would do semantic
| operations on the AST is fricking hard and likely to be very non-
| ergonomic. Look at all the attempts to make code refactoring
| tooling: it's crazily complex and confusing that it's simpler to
| just go and grep for a string and fix anything you find.
|
| As long as it's faster to use regular editing operations to
| shuffle code around, indent or unindent it (or wrap it with
| braces), tweak one thing here or there, simple text editors will
| mostly rule the world of programming.
| mjevans wrote:
| go fmt is really nice, that there is A standard for the
| language which is just included. No more arguments, just do
| what the including tooling desires.
|
| Python... I'd love if it shipped with a formatter that
| converted indents to braces, and then had an option for
| expressing indent as spaces (with number of spaces per indent)
| OR tabs (same, default 1); then still kept the braces.
| lionkor wrote:
| All significant characters should be non-empty/visible, I think
| that sums up why I prefer braces.
| Culonavirus wrote:
| Only monsters prefer invisible characters having syntactic
| meaning, and most of them probably also like pineapple on
| pizza. Shameful. (j/k)
| makeitdouble wrote:
| It's weird to me to as a programmer to categorize space/tabs
| and new lines as empty or invisible.
|
| It only makes sense if you're writing by hand on paper or
| designing a page, sure wherever you don't write is empty. But
| even then that's still visible space.
|
| Then most language we currently use still rely on spaces in
| critical ways. `public function a()` and `publicfunctiona()`are
| not equivalent and there's no replacement character for the
| spaces.
|
| Now, more power to you to like braces, same way some languages
| like dollar signs.
| dmurray wrote:
| > At the moment, Bython is written in Python.
|
| PR #1: Makes Bython self-hosting
| calmbonsai wrote:
| With Python, use Black or go home.
___________________________________________________________________
(page generated 2024-07-07 23:00 UTC)