Live data from Hacker News

Writing a C compiler in 500 lines of Python (2023)

vgel.me

101–110 of 114 posts

Re: Writing a C compiler in 500 lines of Python (2023)

#101
post #83

Earlier quoted context omitted.

> I'm not sure if that's what you meant; the ML approach is quite different. There is a difference in approach because in Common Lisp each method is a separate function definition (though macros can alleviate this), but my point is that both CL and ML are more function-oriented, if you will; i.e. "methods" (or whatever you want to call ML pattern-matched functions) aren't defined in a class body and are just ordinary…

Oh, thanks! I didn't know that about defgeneric . How would you classify Ruby? You can reopen a class and add more methods to it at any time.

Well, reopening the class is the idiomatic way to define a method after the class definition, but if I wanted to write Ruby the ML/Common Lisp way, I would use "Class.define_method" like so:

  String.define_method :yell do
    puts self.upcase
  end

  Numeric.define_method :yell do
    self.to_s.yell
  end
What I like most about Ruby is how close it gets to Lisp's flexibility of semantics (i.e. macros) without actually having macros. (Common Lisp is still my favorite language for larger projects though.)

Re: Writing a C compiler in 500 lines of Python (2023)

#102

Earlier quoted context omitted.

Thanks for the reply. I had asked because I was thinking of getting some small device like a PDA or programmable calculator, to use to write small programs for fun and possibly actual use, when I'm not with my laptop. I am not sure if any PDAs or such calculators are still made these days. I have googled some, but so far did not find any, IIRC. So I may have to buy a used calculator or PDA, if I can find a model I li…

HP 's graphing calculators are the best, but they can be very expensive. Every major calculator manufacturer makes modern back-lit full-color graphing calculators, like HP's Prime, TI's Nspire, and Casio's ClassWiz, but they don't have the charm of reflective LCDs. The best bang for your buck is probably a Casio FX 7400, 9750 or 9860 GIII series, which have Python interpreters. If you want something more fun, albeit…

Thanks again. I will check out those options and links.

Re: Writing a C compiler in 500 lines of Python (2023)

#103
post #83

Earlier quoted context omitted.

Oh, thanks! I didn't know that about defgeneric . How would you classify Ruby? You can reopen a class and add more methods to it at any time.

Well, reopening the class is the idiomatic way to define a method after the class definition, but if I wanted to write Ruby the ML/Common Lisp way, I would use "Class.define_method" like so: String.define_method :yell do puts self.upcase end Numeric.define_method :yell do self.to_s.yell end What I like most about Ruby is how close it gets to Lisp's flexibility of semantics (i.e. macros) without actually having macros…

Hmm. I'll have to think about that.

I still feel like ML is very much the odd one out, here, because the individual pattern-matching clauses aren't values and can't be added later except by editing the "generic" function (and usually the definition of its argument type).

Re: Writing a C compiler in 500 lines of Python (2023)

#104
post #23

I find it surprising that a single-pass compiler is easier to implement than a traditional lexer->parser->AST->emitter. (I'm not a compiler expert, though.) I'd have expected that generating an AST would be at least as simple, if not simpler. Plus by generating an AST, doing some simple optimization is a lot easier: one can pattern-match parts of the AST and replace them with more efficient equivalents. Maybe I'm ove…

I think this might depend on the language you're writing in. Historically, at least, it's pretty verbose to define a data type in Python compared to languages that are more designed for writing compilers. Consider these definitions from my prototype Bicicleta interpreter, which is written in ML, specifically OCaml: type methods = NoDefs (* name, body, is_positional ... *) | Definition of string * bicexpr * bool * met…

Eli Bendersky's blogpost on the Expression Problem: https://news.ycombinator.com/item?id=45155877

Re: Writing a C compiler in 500 lines of Python (2023)

#105
post #104
post #23

Earlier quoted context omitted.

I think this might depend on the language you're writing in. Historically, at least, it's pretty verbose to define a data type in Python compared to languages that are more designed for writing compilers. Consider these definitions from my prototype Bicicleta interpreter, which is written in ML, specifically OCaml: type methods = NoDefs (* name, body, is_positional ... *) | Definition of string * bicexpr * bool * met…

Eli Bendersky's blogpost on the Expression Problem: https://news.ycombinator.com/item?id=45155877

I thought this was a good read, and it’s clearly a problem in an OO language, but I struggled to see how it’s an actual problem in a functional language. Maybe I need to go read that paper he referenced by the Racket guys.

Re: Writing a C compiler in 500 lines of Python (2023)

#106

Earlier quoted context omitted.

As an ex-Gentoo user I can confirm that compiling speed still matters on certain machines.

I have never worked as a system programmer so I never had the need to compile something big. I guess it could be an issue with very large software like Oracle Database, the Linux kernel and other similar stuffs.

The kernel is quite okay. On the other hand, qtwebengine..

Re: Writing a C compiler in 500 lines of Python (2023)

#107
post #104

Earlier quoted context omitted.

Eli Bendersky's blogpost on the Expression Problem: https://news.ycombinator.com/item?id=45155877

I thought this was a good read, and it’s clearly a problem in an OO language, but I struggled to see how it’s an actual problem in a functional language. Maybe I need to go read that paper he referenced by the Racket guys.

The example in the article was very clear I thought: try to extend an interpreter with a new primitive (function call in the article) without changing the original interpreter's source code. I'm an FP language, you can't extend the core AST without changing the source code for eval.

Re: Writing a C compiler in 500 lines of Python (2023)

#108
post #104

Earlier quoted context omitted.

Eli Bendersky's blogpost on the Expression Problem: https://news.ycombinator.com/item?id=45155877

I thought this was a good read, and it’s clearly a problem in an OO language, but I struggled to see how it’s an actual problem in a functional language. Maybe I need to go read that paper he referenced by the Racket guys.

In my example above, to add a new variant type to bicexpr, you need to edit roughly every function that pattern-matches on bicexprs, which is a good fraction of the Bicicleta interpreter codebase.

Re: Writing a C compiler in 500 lines of Python (2023)

#109
post #108

Earlier quoted context omitted.

I thought this was a good read, and it’s clearly a problem in an OO language, but I struggled to see how it’s an actual problem in a functional language. Maybe I need to go read that paper he referenced by the Racket guys.

In my example above, to add a new variant type to bicexpr, you need to edit roughly every function that pattern-matches on bicexprs, which is a good fraction of the Bicicleta interpreter codebase.

Ah, I see. I’ve written that code where you have to add one case to a whole bunch of pattern matches. It’s not terrible; I rather like that everything that does the same thing is in the same place. But I have wondered if there was a better way. Clearly I need to go read the article again.

Re: Writing a C compiler in 500 lines of Python (2023)

#110
post #108

Earlier quoted context omitted.

In my example above, to add a new variant type to bicexpr, you need to edit roughly every function that pattern-matches on bicexprs, which is a good fraction of the Bicicleta interpreter codebase.

Ah, I see. I’ve written that code where you have to add one case to a whole bunch of pattern matches. It’s not terrible; I rather like that everything that does the same thing is in the same place. But I have wondered if there was a better way. Clearly I need to go read the article again.

Yeah, I share your assessment that it's not unmanageable.

But it does add friction. I suspect that there are only two real solutions:

- program source code that isn't a linear document but instead can be viewed in multiple different ways: by operation or by operand type, for example. Then you would use the view that best suits the modification you were doing at the time. Smalltalk, for example, does support browsing either all the implementors of a method selector or all the methods of a class. (But in both cases you normally only see one method at a time.)

- Alternating levels of hierarchy. Maybe if you have 63 operations on 63 types, you could arrange it so that you can add a 64th operation or a 64th type by editing only 8 places instead of 63.

Post reply on HN