Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I started learning programming with modern dialect of BASIC and when I first tried Lua, I've had my mind blown when I discovered:

  - tables (hashmap)
  - regex
  - pass by reference (caused a lot of confusion and frustrating bugs)
  - metatables
  - goto and labels
  - multiple return values
After Lua I did want to try a language that's fast, something compiled to small native binary. My choice was Nim. And Nim got my mind blown to pieces:

  - static types
  - function declarations I can understand how to use without reading their code
  - functional paradigm
  - batteries included standard library
  - compile-time functions
  - generics
  - templates
  - macros
  - exploring and manipulating AST
  - const, let, var (immutability)
  - pointers and references
  - compiler optimizations
  - move semantics
  - memory management
  - I can compile code to both javascript and C?!
  - C, C++ and JS interop (ffi)
  - I can read and understand source code of standard library procedures?!
  - huh, my computer is fast, like crazy fast!!
  - and probably more, but that's what I can recall now..


Lua is absolutely pass by value. You’re probably mixing container values with by-reference, that is a common mistake. Pass by reference means that an assignment to an argument updates the variable at the call site, e.g.:

  local x = 0
  function f(byref arg)
    arg = 1
  end
  f(x) -- x == 1
Except that there’s no “byref” in Lua and no way to access the original argument’s location (commonly “lvalue”).

Passing a table to a function and not receiving a deep/shallow copy is still “by value”, not “by reference”, because “by” here is about variables (lvalues), not values.

Edit: removed more confusing parts


To clarify what I meant by "pass by reference" here's excerpt from the Lua 5.1 manual:

> Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.

I also seen this described as "reference semantics" and "value/copy semantics", maybe that would be a better term?


I see, sorry for the noise then. I’m programming since the '90s but still not sure what the correct term would be here, so, yeah.

When we use exactly “pass[ing] [an argument] by reference” it usually means passing an argument by a reference to its location (opposed to contents). I think we just avoid using that exact form if we want different meaning, there’s no proper form. Cause applying it to values rather than arguments rarely makes sense. Copy semantics are non-trivial in general. Shallow copying may not be sufficient to create a proper copy and deep copying may copy half of the vm state, think f(_G, debug.getregistry()).

The Lua manual probably had the same issue with wording it.

Again, C++ with copy constructors is an exception here. You usually receive a copy (shallow or deep depends on a constructor) if no reference, pointer or move semantics given. That was the edit-removed part above.


Yeah, it's a routinely mistaken term in CS, I have met plenty interviewer who I had to correct on it (most languages, but java is also pass-by-value. It just passes objects by pointer value. C is also always pass-by-value. C++ is one of the few exceptions, it does have pass-by-reference semantics)


That idea `function can return multiple values` was a bit of `Wait what? Ah I almost forgot :facepalm:` moment for me. (The quadratic formula function for solving quadratic equations `ax^2 + bx + c = 0` returns TWO values.)




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

Search: