Hacker News new | past | comments | ask | show | jobs | submit | kbp's comments login

It works the same way in Haskell, eg

  main = do
    let x = 2
    let x = "foo"
    y <- pure 3
    y <- pure "bar"
    putStrLn $ x ++ y
which is really the same as

  main =
    let x = 2
    in let x = "foo"
       in pure 3 >>= \y ->
                       pure "bar" >>= \y ->
                                        putStrLn $ x ++ y
So it works pretty naturally where each assignment is kind of like a new scope. If the type system is good, I don't think it really causes issues.


Haskell has got to be by far the least readable language in the world, all of that is incomprehensible


I'm not sure what you find incomprehensible about the first example. The syntax is pretty standard. The only exotic thing is `$`, which is basically just like putting brackets around the rest of the line. Here's the first example roughly translated to Python:

  def main():
      x = 2
      [x] = ["foo"]
      y = 3
      [y] = ["bar"]
      print(x + y)
Seems about the same level of comprehensibility to me. Is there anything in particular you find difficult to understand?

The second example is expanded out and not how a person would normally write it, but if you're familiar with the basic concepts it's using, it shows why it works very clearly; think of it like assembler.


Er, actually

  x = 2
  x = "foo"
  [y] = [3]
  [y] = ["bar"]
Sorry, I didn't re-read the code before translating.


Surely not in Canada?


I can hear them and tell that they're different accents, but I don't really distinguish them, I would call them both "British" and I wouldn't know which one's more posh.


Usually that effort should go toward naming functions rather than their results, though, and if the functions have good names, the results don't need them. In this example, `other_function` could have been named `get_user_data`, `new_function` could have been called `extract_user_details`, whatever.

Once you have good function names, which you should generally be spending a lot more effort on than good local variable names, you won't find any value in adding variables like `var foo = get_foo()`.


Works in Ruby:

  irb(main):001:1/ puts(%r
  irb(main):002:1* a+
  irb(main):003:0> .match? %q aaa )
  true


You can also ssh in via Emacs with Tramp, and use your highly customised Emacs to edit remotely.


Unsigned integers are still specified to wrap.


> Clojure has cons, car, cdr which you can use in the classic Lisp sense. The only thing you CAN'T do is have a dotted pair or dotted list in the last cons cell.

So, it doesn't have them in the classic Lisp sense. Conses are just pairs. Using them as such isn't exotic. (cons 1 2) being an error in Clojure isn't a minor thing, it's very unique compared to other Lisps. It has a very different definition of cons.


Yes. Clojure doesn't have cons cells in the traditional sense. But as long as you don't need dotted cdrs, you can "think" of using cons, car, cdr in the ordinary way. You can use existing lisp idioms of recursively taking apart, editing and rebuilding a complex form.


That isn't how that defun would normally be formatted, though. Lisp knows that the 'body' part starts with the 3rd argument (the same way Clojure knows it starts with the second), so it indents the lambda list farther right (if it doesn't fit on the first line, otherwise it would go there).

For my eyes, [] aren't distinct enough from () to make the second style preferable. I'd rather have indentation to set it apart.


I just made them consistent. It certainly helps me visually. Also a list implies you intend to evaluate it by executing a function. A vector implies you do not intend to call a function.


Yeah, it's definitely a taste thing, but as the first style isn't used in Lisp, comparing its readability doesn't really make sense. Indentation is important to reading Lisp. Indenting it in an odd way makes it harder to parse. It's a bit like giving

  def
    foo(x)
    bar(x)
  end
as an example of Ruby syntax being overly homogeneous.


  (defun averagenum (n1 n2 n3 n4)
    (/ (+ n1 n2 n3 n4)
       4))
The typical pattern is

  DEFSOMETHING name arglist
   
    body
A Lisp programmer reads those structural patterns, not the delimiters.

Lisp programming is more about thinking of trees of code and their possible manipulation - even independent of a visual notation and especially independent of the exact delimiter used.

The delimiters are in shape recognition much less important than the shape itself.


"A Lisp programmer" ... Sheesh, I am a lisp programmer, man, and I assure you I know what trees of code independent of visual notation is. You're making a point that doesn't need to be made here. It's this kind of phrasing that really turns off people from the lisp community.

I wrote it that way so it's easier for non-lisp programmers to compare with what they're more used to as well.


That doesn't help them. Explain it like it is. Lisp is different from what they are used to.


Could you expand on how Forth differs from Lisp? I don't know Forth.


In Forth, the interpreter reads tokens. By default, each token is read and then executed. There is a token that switches the interpreter into "compiling" mode. When in compiling mode, each token is read and then used to instruct the compiler to emit code representing the token. There is a traditional and beautiful interplay [0] between the Forth interpreter and its initial stream of tokens, as the tokens customize the interpreter and compiler by augmenting their behaviors.

The main contrast that I would draw between Forths and Lisps is syntax. Forths don't really have syntax; they have token-parsing streams. Lisps are extremely tree-oriented, but Forths are stack-oriented.

[0] https://github.com/nornagon/jonesforth


Forth has two singleton stacks, and each has a DSL. Sometimes I wonder what Forth would be like with stacks as a first-class type. Maybe actors each with their own stack …


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: