Live data from Hacker News

How to Implement a Programming Language in JavaScript

lisperator.net

11–20 of 36 posts

Re: How to Implement a Programming Language in JavaScript

#11
post #7

I've written multiple parsers/interpreters in both JS and Python -- Python being my favorite language. From that experience, I've come around to the fact that they're both the wrong language for writing languages -- lexers, parsers, interpreter loops, compilers. I have a good analogy to explain this. Take this OCaml program. let sum_file filename = let file = In_channel.create filename in let numbers = List.map ~f:In…

I agree with you in principle. After all, "ML" got its name "metalanguage" from the fact that it was explicitly designed to be a domain-specific language for implementing programming languages. It's hard to be a DSL at its job.

At the same time, that has to be balanced with the ecosystem value of implementing your language in a language lots of others knows.

It's a worthwhile investment to implement your language with 4x the code in Python/Java/JS/etc. if you get more than 4x contributions because of it.

Re: How to Implement a Programming Language in JavaScript

#13
post #7

I've written multiple parsers/interpreters in both JS and Python -- Python being my favorite language. From that experience, I've come around to the fact that they're both the wrong language for writing languages -- lexers, parsers, interpreter loops, compilers. I have a good analogy to explain this. Take this OCaml program. let sum_file filename = let file = In_channel.create filename in let numbers = List.map ~f:In…

I 100% agree that JS and Python are the wrong language for writing languages. Haskell, however gets you the best of both worlds. Your sum_file function in Haskell would look like this:

    sumFile :: FilePath -> IO Int
    sumFile file = sum . map read . lines  readFile file
I don't think many people would dispute that Haskell is at least as good as OCaml for writing languages. And strangely enough, the most advanced Perl 6 implementation is even written in Haskell!

Re: How to Implement a Programming Language in JavaScript

#14
post #7

I've written multiple parsers/interpreters in both JS and Python -- Python being my favorite language. From that experience, I've come around to the fact that they're both the wrong language for writing languages -- lexers, parsers, interpreter loops, compilers. I have a good analogy to explain this. Take this OCaml program. let sum_file filename = let file = In_channel.create filename in let numbers = List.map ~f:In…

I agree with you in principle. After all, "ML" got its name "metalanguage" from the fact that it was explicitly designed to be a domain-specific language for implementing programming languages. It's hard to be a DSL at its job. At the same time, that has to be balanced with the ecosystem value of implementing your language in a language lots of others knows. It's a worthwhile investment to implement your language wit…

> It's a worthwhile investment to implement your language with 4x the code in Python/Java/JS/etc. if you get more than 4x contributions because of it.

Maybe, but I'd say it depends on the quality of the contributions.

Re: How to Implement a Programming Language in JavaScript

#15
post #7

I've written multiple parsers/interpreters in both JS and Python -- Python being my favorite language. From that experience, I've come around to the fact that they're both the wrong language for writing languages -- lexers, parsers, interpreter loops, compilers. I have a good analogy to explain this. Take this OCaml program. let sum_file filename = let file = In_channel.create filename in let numbers = List.map ~f:In…

I 100% agree that JS and Python are the wrong language for writing languages. Haskell, however gets you the best of both worlds. Your sum_file function in Haskell would look like this: sumFile :: FilePath -> IO Int sumFile file = sum . map read . lines readFile file I don't think many people would dispute that Haskell is at least as good as OCaml for writing languages. And strangely enough, the most advanced Perl 6 i…

Right, I was referring to all ML-based languages -- so SML, OCaml, Haskell, F#, and possibly even Rust.

Do you know how this would look in Haskell?

    # Return K most common lines in a file

    def top_k(f, k):
      counts = collections.defaultdict(int)
      for line in f:
        counts[line] += 1

      return sorted(counts.items(), key=lambda x: x[1], reverse=True))[:k]
    
       
I was actually looking for the OCaml example which does this. I think it was in "Real World OCaml", and I remember it being horribly ugly compared to Python. I couldn't find it though.

Re: How to Implement a Programming Language in JavaScript

#16
post #7

I've written multiple parsers/interpreters in both JS and Python -- Python being my favorite language. From that experience, I've come around to the fact that they're both the wrong language for writing languages -- lexers, parsers, interpreter loops, compilers. I have a good analogy to explain this. Take this OCaml program. let sum_file filename = let file = In_channel.create filename in let numbers = List.map ~f:In…

Your comparison isn't really fair. With similar functions from Core's In_channel you can write something like:

  let sum_file filename =
    with_file filename 
      (fold_lines ~init:0 ~f:(fun a l -> a + int_of_string l))
"Using the right tool for the job" when it comes to functional vs. "mainstream" languages is a popular meme, but it doesn't hold up to scrutiny. You can always write your own higher-level code for a given domain with a reasonably expressive language. Adding a useful type system, ADTs, etc. to a language like Python is much, much harder (though that's exactly what Microsoft and Google are trying with Javascript).

Re: How to Implement a Programming Language in JavaScript

#17
post #7

I've written multiple parsers/interpreters in both JS and Python -- Python being my favorite language. From that experience, I've come around to the fact that they're both the wrong language for writing languages -- lexers, parsers, interpreter loops, compilers. I have a good analogy to explain this. Take this OCaml program. let sum_file filename = let file = In_channel.create filename in let numbers = List.map ~f:In…

I agree with you in principle. After all, "ML" got its name "metalanguage" from the fact that it was explicitly designed to be a domain-specific language for implementing programming languages. It's hard to be a DSL at its job. At the same time, that has to be balanced with the ecosystem value of implementing your language in a language lots of others knows. It's a worthwhile investment to implement your language wit…

That's definitely a consideration, depending on your goals. For many language projects, I don't think you need more than one person for the front end. For libraries and code gen, you definitely need contributions.

IMO it's actually advantageous to have a compact description of a lexer, parser, and AST that one person edits or very few people edit. That's your language design.

At one point I thought: "If ML is so great, then why don't you see it more often in the real world?" And then the revelation was that Python essentially uses ML to describes its AST:

http://svn.python.org/projects/python/tags/r32b1/Parser/Pyth...

This is Zephyr ASDL, an ML-inspired DSL for describing ASTs. A lot of ML people may recognize Andrew Appel from the authors list:

https://scholar.google.com/scholar?cluster=11682730813888505...

So my favorite language's AST is described with ML!!! And has been for 10+ years. (Python has a Grammar file as well in a different syntax).

I'm actually interested in a hybrid architecture: an interpreter where OCaml generates the byte code, and then C++ executes it. I think you can produce extremely compact and flexible interpreters with this architecture, and there are several other advantages to dividing it this way.

The downside is perhaps a more complex build process, but the OCaml toolchain is quite nice actually, and I have compiled it from scratch. It's head and shoulders above Haskell in that regard. OCaml can produce .o files and link with C/C++, so you still get one executable.

I looked at your Wren language which I like a lot. I did wish the front end was more high level and not in C, but that's just me :)

There are a lot of people coming around to OCaml. Facebook is using it for Flow and pfff language manipulation:

https://github.com/facebook/pfff (I suspect Google's code analysis tools would be cut down in size by 5x if written like this in OCaml.)

And Hack, the statically typed PHP, is written in OCaml. And there are several more minor languages like HaXe and another one that are OCaml.

So if you're looking for contributions from language experts, there's definitely a lot that are familiar with OCaml.

Re: How to Implement a Programming Language in JavaScript

#18
post #16
post #7

I've written multiple parsers/interpreters in both JS and Python -- Python being my favorite language. From that experience, I've come around to the fact that they're both the wrong language for writing languages -- lexers, parsers, interpreter loops, compilers. I have a good analogy to explain this. Take this OCaml program. let sum_file filename = let file = In_channel.create filename in let numbers = List.map ~f:In…

Your comparison isn't really fair. With similar functions from Core's In_channel you can write something like: let sum_file filename = with_file filename (fold_lines ~init:0 ~f:(fun a l -> a + int_of_string l)) "Using the right tool for the job" when it comes to functional vs. "mainstream" languages is a popular meme, but it doesn't hold up to scrutiny. You can always write your own higher-level code for a given doma…

FWIW I took it straight out of Real World OCaml, assuming that that's idiomatic OCaml.

See my other comment -- how does top K lines in OCaml look? I recall that was in the book too, but couldn't find it. I remember it being fantastically ugly.

Re: How to Implement a Programming Language in JavaScript

#19
post #15

Earlier quoted context omitted.

I 100% agree that JS and Python are the wrong language for writing languages. Haskell, however gets you the best of both worlds. Your sum_file function in Haskell would look like this: sumFile :: FilePath -> IO Int sumFile file = sum . map read . lines readFile file I don't think many people would dispute that Haskell is at least as good as OCaml for writing languages. And strangely enough, the most advanced Perl 6 i…

Right, I was referring to all ML-based languages -- so SML, OCaml, Haskell, F#, and possibly even Rust. Do you know how this would look in Haskell? # Return K most common lines in a file def top_k(f, k): counts = collections.defaultdict(int) for line in f: counts[line] += 1 return sorted(counts.items(), key=lambda x: x[1], reverse=True))[:k] I was actually looking for the OCaml example which does this. I think it was…

I would do it something like this:

    top xs = map fst $ sortBy (compare `on` Down . snd) $
        M.toList $ foldr (\x -> M.insertWith (+) x 1) mempty xs
This has the type `top :: Ord a => [a] -> [a]`. You might object that I didn't include your k parameter. Because Haskell is a lazy language, I can get your behavior very simply by doing `take n . top` and it will lazily only calculate the first n values. This gives you more abstractive power and lets you write more composable code.

Re: How to Implement a Programming Language in JavaScript

#20
post #15

Earlier quoted context omitted.

I 100% agree that JS and Python are the wrong language for writing languages. Haskell, however gets you the best of both worlds. Your sum_file function in Haskell would look like this: sumFile :: FilePath -> IO Int sumFile file = sum . map read . lines readFile file I don't think many people would dispute that Haskell is at least as good as OCaml for writing languages. And strangely enough, the most advanced Perl 6 i…

Right, I was referring to all ML-based languages -- so SML, OCaml, Haskell, F#, and possibly even Rust. Do you know how this would look in Haskell? # Return K most common lines in a file def top_k(f, k): counts = collections.defaultdict(int) for line in f: counts[line] += 1 return sorted(counts.items(), key=lambda x: x[1], reverse=True))[:k] I was actually looking for the OCaml example which does this. I think it was…

The ocaml version of this code would be actually quite similar, since you can even use imperative hash tables if you want. The syntax is a bit fugly and the stdlib doesn't have some of the helpers python has but I wouldn't go as far as say that its "horribly ugly". Beauty is in the eye of the beholder and Ocaml has the advantage of being much less "magical" than python (as per the "explicit is better than implicit" mantra)

* In ocaml you need to pass some "comparator" parameters around if you want top_k to be polymorphic. Its similar to haskell type classes but you need to be explicit... * Instantiating a polymorphic hash table is a bit ugly but thats more about the standard library... * There is no "default dict" function so you would need to initialize the counts yourself * Looping the file is not hard. Most data structures will have some sort of "fold" or "iter" function you can use. * The sorting function doesn't take keys, so you need to use a comparator instead. Its not that bad though - the function to convert a hash table into a list already returns a list of tuples.

Post reply on HN