Recent submissions

Comment · 8 years ago
You were being overpessimistic: Python's GC handles cyclic references perfectly well.
Comment · 9 years ago
I don't think anyone manually counts out their tabs and spaces, but I think every major text editor has a mode or plugin to make this automatic.
Comment · 9 years ago
A is indented with a tab.

B is indented with a tab, plus the requisite number of spaces to line up with the above line.

C is indented with a tab.

Comment · 9 years ago
> My girlfriend is MOSTLY supportive but I don't dump everything on her. Learn to deal with stuff yourself and you'll be happier.

Learning to deal with stuff yourself doesn't preclude asking your partner for help with making a decision that can impact both of you for the rest of your lives.

Comment · 9 years ago
What kind of guarantees do you want from your type system? Strictly speaking the only guarantee that linear types give you is that every single linear value will be consumed at some point, which generally means that no resources ever get "leaked". If the idea of accidentally leaking a resource is unacceptable to you then you might find that affine types are too flexible, as languages that implement affine types generally give you some way to leak a value.

In practice I don't know if anyone is overly concerned about this. While Rust doesn't have linear types, I find you have to bend over backwards to introduce a situation where you might accidentally leak a resource.

Tarean makes a good point with respect to fusion, but "guaranteeing" fusion requires additional assistance from the compiler in addition to the basic implementation of linear types.

Comment · 9 years ago
Yep -- actually, if you look at how the IO type is defined in Haskell, it looks basically like this (there is an object that represents the "state of the world" that gets threaded through computations).
Comment · 9 years ago
Not sure what you're asking here. Usually the semantics behind what happens to an unused variable (i.e. is the file automatically closed, etc.) come down to how the language is designed. It could be automatically destroyed (like RAII in C++) or it could just be forgotten.

In a purely functional language with affine types, unused variables are usually just optimized out.

Comment · 9 years ago
Depends on the implementation of the language. In a typical functional language with linear types, the functions that mutate an object return a "new value" that is conceptually a modified version of the first value. So fleshing out our example:

    open : () -> File
    close : File -> ()
    write : (File, String) -> File
    let f: File = open()
    let new_f : File = write(f, "Hello world!\n")
    close(new_f)
If this seems clumsy or error-prone, notice that you can't accidentally close() f instead of new_f, and you can't forget to close() new_f, so there is actually very little room for error here.
Comment · 9 years ago
Linear types = "you must use this value exactly one time" Affine (uniqueness) types = "you can use this value either zero or one times, but you can't use it more than once"

As an example, compare two languages: one with linear types and one with affine types. Let's say that you had a "File" type, a function "open()" that creates a file (either linear or affine as appropriate), and a function "close()" that consumes the file. Then this code would be legal in both languages with linear types and languages with affine types:

    let f: File = open()
    close(f)
Note that "f" is used once and only once, at which point the value is consumed. In a language with affine types, this is also kosher:

    let f: File = open()
    // Do nothing
This fails to compile in the language with linear types because "f" is never used. Finally, this code is never legal in either language:

    let f: File = open()
    close(f)
    close(f)
... because "f" is used twice here, and neither linear types nor affine types allow that.

So affine types give you a little more leeway.

Comment · 9 years ago
Why are you under the impression that what Apple calls "ARC" is substantially different than reference counting?
Comment · 9 years ago
> I mean... you could have just called it a ref. ref T instead of &T. And then just ref(foo) or foo.ref to get a ref to foo.

Ugh, no. There are references all over the place when I write Rust code -- it would be a serious bummer for me if annotating those types and making those references took up 4 characters for "ref " instead of just the 1 for &.

Comment · 9 years ago
Haskell is a compiled language.
Comment · 9 years ago
I have not seen any evidence that GC is the primary bottleneck in Haskell, or that a form of compiler-driven manual memory management would be faster.
Comment · 9 years ago
> Except you can bound it, and you can escape it that way. IE "not gotten anywhere after 30 iterations, so don't know".

It should go without saying that this system is not Turing-complete anymore if you bound the runtime.

Comment · 9 years ago
Have there been writings on what exactly git's migration strategy to a new hash function will be? Apparently they have a seamless transition designed that won't require anyone to update their repositories, which seems like a pretty crazy promise in the absence of details.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton