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

Well, depends what he means with "your"; OP specifically, or an arbitrary person? Because I think we are getting dangerously close to shooting down useful criticism and discussion for fear of hurting someones feelings. It's obviously insensitive to say that OP is a bad person because he is doing one-on-ones, but it should be totally acceptable to say "this is weird (from my perspective), I can see several issues with this, I wouldn't personally do this, but you-do-you", and often "(from my perspective)" and "but you-do-you" parts are implied; their absence shouldn't necessarily be taken as proof of mocking.

(Disclaimer: I have no opinion on partner one-on-ones.)


Weird is one of those truly terrible words that's used to control people who are different than us. It's nice for the person using it, since it doesn't actually mean anything and is thus impervious to arguments stronger than "nuh uh". It's almost never actually the right word, and should be avoided in favor of more descriptive language. In order for criticism to be constructive, it must be easily understandable by the person receiving it.

"Don't call people weird" seems like a good general principle (unless they self-identify as weird, in which case knock yourself out). I don't understand this compulsion to try and get people to fall in line and stop being weird.

The from-my-perspective and you-do-you parts are the most important parts, why would you leave them out? You're not in charge.


Apparently the developers are reading this thread, so I have a request: Please reduce your website's dependence on javascript. Doesn't leave a great impression when I need to fiddle with noscript before seeing static text.


I would do more of this if I had a simpler way of pulling documentation from the GitHub Wiki repo.

I’m sorry the experience was poor, and I’ll consider this feedback as I make improvements to our documentation and marketing collateral to make it nicer to use. My apologies. I work hard to win over developers, many times one at a time, and so your feedback isn’t lost on me.


No; lookup Calculus of Construction. Dependent types allows you to specify an dependence between different values in your type directly within your type system; which has great implications for type safety and so on.

A classic example is that you can specify the 2-vectors on the unit circle as "{ (x,y) : x,y in R | x^2 + y^2 = 1 }" (read as "the set of real 2-tuples, where their norm is equal to 1".) This is not possible in most languages; the closest you can get in most languages is "{ (x,y) : x,y in R }".

My personal pet peeve with dependent types and proof-driven programming in general is the wealth of options in formulating propositions. I've seen at least five different ways of defining equivalency.


>you can specify the 2-vectors on the unit circle as "{ (x,y) : x,y in R | x^2 + y^2 = 1 }"

Which is not possible for any language targeting real machines since floats have fixed precision.


You can specify the 2-vectors on the unit circle as "{ (x, y) : x, y in R | x^2 + y^2 - 1 < 0.000001 }" instead.


To clarify, "great implications" can mean "undecidability".


I do not really agree with the article's (implied?) statement that multivalues are an ugly part of Lua. It's subtle yes, but like most of Lua, is incredibly consistent.

For example, let's compare with Python: In Python, you can return multiple arguments as a tuple; it's not possible to have an optional return value without a lot of painful type matching and unpacking. In Lua you can:

  local result, errmsg  =  do_stuff()
  if not result then
    error("Error in do_stuff:"..errmsg)
  end
  print(result + 5)
If you don't want the error message, just remove ", errmsg", and it will work as expected. This is incredibly flexible, which is exactly what I want in my dynamic languages. In Python, you would get an type error when attempting to add together a tuple and an integer.


The equivalent Python would be:

    result, errmsg = do_stuff()
    
    if errmsg:
      error(f"Error in do_stuff: {errmsg}")
    
    print(result+5)
Assuming that errmsg is 'None' when do_stuff() succeeds.


Can you unpack tuples in Python? In JS for example you could write

    const [result, errmsg] = do_stuff();
And I guess you would be fine to omit the errmsg, even though I admit the resulting [result] syntax would be dissatisfying


But why not just use a table in this case? Indexing a value that doesn't exist will give you nil as well.


Tables require dynamic allocation--as do Python tuples--which cause GC churn even when optimized. And accessing a table performs a lookup operation just to put it onto the value stack, anyhow. While insertion and index operations are fast, they're nowhere near as fast as not doing them at all. If you want stack semantics, just use the stack! Multiple return values (return lists) are one reason why Lua is often faster than Python and JavaScript in an apple-to-apples (i.e. comparing ad hoc application logic that doesn't rely on Python's hundreds of megabytes of C modules, no JIT (though return lists make JIT'ing easier), etc). The article says that they "don't perform notably better", but in my 15 years of experience with Lua that's just absolutely not true, especially on hot paths.

But return lists are more than an optimization. Lua is a first-class functional language with guaranteed tail-call optimization. And Lua maintains strong semantic symmetry between its C API and in-language constructs. In both cases return lists provide an extremely elegant way for composing function calls, including composing mixtures of Lua and Lua C functions.

For example, returning a list in C is as simple as `push; push; return 2`, whereas in languages that require an array or tuple you need to need to create a separate object and then insert your value (by index or name). It's worth noting that Lua can handle allocation failure gracefully, throwing an error back to the more recent protected call while maintaining a clean state (e.g., OOM from an event loop client handler won't crash your app and the hundreds of thousands of other connections). Many simple functions that operate on the stack (e.g. lua_pushinteger) are guaranteed not to dynamically allocate. Such guarantees can make writing OOM-safe Lua C API code much easier.

If you look at it from the perspective of the C FFI, return lists make a ton of sense. Indeed, they're integral to the C API semantics, which is defined in terms of an abstract invocation stack--which is in fact implemented as a contiguous array.


This explanation went far more in depth than I expected it to. Thanks for writing it out!


Syntax-wise, I can understand what's going on with this code at a glance. I wouldn't get that from a table. It's as much expressiveness as capability.


Pedantic point: The whole "reading the bible in Latin" is a very Catholic thing (and maybe Orthodox?). The Protestant churches I've been in has read from the bible in the native tongue, and it was indeed one of Luther's criticisms of the Catholic church.


I'm not Catholic, but I think they stopped requiring the reading of scripture in Latin around 1960 and The Second Council of Vatican, AKA Vatican II.

I think Latin is still used as part of the traditional service, but it's mostly ritualistic. What I remember from attending Catholic services years ago is a lot of standing up and sitting down while chanting in Latin, followed by a sermon delivered in English.


It's not universal either. I've grown up in a catholic-obsessed country and not a single mass I've been to had Latin elements or chanting. All in native language in mid 80s.


Well, yes, it would be that hard.

The whole idea with tail call elimination is that a stack trace shouldn't be able to see the frames for the tail calls, because the tail call reuses the frame. To add support for tracking the tail call stack frames, you would need to modify the compiler to output code that specifically keeps track of "elided tail call frames", and you would need to update the stack trace traversal code to be able to recognize the extra debug information.

Sure, it's something you could build into a new toolchain, but adding something like this to the JVM would be harder due to the constraints already placed on the JVM. Furthermore I don't know of such support in any toolchains, not even for Lua or Scheme, both of which guarantee tail call optimization. (If anybody has an example, please share!)


Lua's stack trace includes an indication that 1 or more tail calls happened, but not how many

  $ cat tailrec.lua
  function f(g,n)
    if n == 0 then
      error("oh no")
    end
    return g(g,n-1)
  end
  f(f,5)
  $ lua tailrec.lua
  lua: tailrec.lua:3: oh no
  stack traceback:
   [C]: in function 'error'
   tailrec.lua:3: in function 'f'
   (...tail calls...)
   tailrec.lua:7: in main chunk
   [C]: in ?


JavaScriptCore keeps track of frames, even for JavaScript proper tail calls: https://webkit.org/blog/6240/ecmascript-6-proper-tail-calls-...


The essential words in that article are...

> There are some non-standard ECMAScript features in JavaScript that work differently in the presence of PTC.

Java has a strict spec, and the relevant methods which would break aren’t non-standard like they are in JavaScript.

If you’re willing to change the spec (I think Loom does) then yeah, but you can’t implement it as an ‘optimisation’ until then, because it’s not an optimisation if it changes behaviour.


What would Java's be? Is there an interface besides Thread.getStackTrace()?


It’s also the format of the backtrack - I think that’s covered by the TCK.


Thanks. It is easy to forget how much reporting is specifically about the US, and that a lot of the rest of the world doesn't really have the same problems.


That sounds more realistic than one might expect. Most printers will apparently reject printing of patterns containing the EURion pattern [1], commonly found on paper cash. Not a far stretch that some facial recognition tech might contain deliberate hidden patterns in the future.

[1]: https://en.wikipedia.org/wiki/EURion_constellation


May be a similar system to Denmark, where one of the major POS system sellers operator sort-of on a subscription basis. The retailers don't own the card machines themselves, but the machines are swiftly replaced when card standards are upgraded.


Not sure where you get those weird infinity results from, but the "a = b = c = 0" solution is easily show:

Note that "a + b = c" implies "b = c - a", and given our assumption that "a = b = c", we can rewrite as "a = a - a = 0". This obviously results in "a = b = c = 0".

EDIT: Modifying the proof above, it becomes apparent that this is a property of groups (most number systems are groups): Again "a + b = c", iff "a + a = a" iff "a + a + (-a) = a + (-a)" which is "a = e".

Note that addition over IEEE754 floats do not constitute a group, (in part) because "inf + inf == inf" evaluates to true.


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

Search: