HNHacker News
TopNewBestAskShowJobs

the_unproven

74 karma · joined October 21, 2018

submissionscomments
the_unproven··on Show HN: Fuse – statically typed functional programming language
This is great, I haven't been introduced in the notion of supercompiliation. Reading the papers you've listed and going through GRIN's paper [1] it ticks the boxes in terms of laziness and graph reduction. To keep the implementation of Fuse simple I've decided on using strict evaluation of GRIN programs instead of laziness, with my assumption that it would harder to debug/reason on the program. However, this was one of my next improvements: switching to a lazy evaluation with similar semantics to Haskell programs.

> It appears that Fuse does not have user-defined operators. Am I right?

Not yet, but I left this mechanism completely open. As operators are defined as type classes with their signs as method definitions.

  [1] http://nbviewer.jupyter.org/github/grin-compiler/grin/blob/master/papers/The%20GRIN%20Project.pdf
the_unproven··on Show HN: Fuse – statically typed functional programming language
Fair point, I don't disagree with the statement that `Self` can be limiting as the trait is defined for `Functor[A]`. Thus imposing limitations on type system.

You would want for type variable to not be attached directly to a type class on its definition? But still treated as a container type. Something like:

    trait Functor:
        fun fmap[A, B](f: A -> B, c: Self[A]) -> Self[B];

     ...

    impl Functor for List[A]:
        fun fmap[A, B](f: A -> B, l: List[A]) -> List[B]
            List::fold(l, Nil[B], (t, h) => Cons(f(h), t))

    ...
The above would compile, but the Functor wouldn't be treated of a higher kind in the type-system. I'll try to work a flexible solution, thanks for the great callout!
the_unproven··on Show HN: Fuse – statically typed functional programming language
Technically yes, although there's no support for FFI yet. Purity would allow it as long as side-effects are wrapped into IO type.
the_unproven··on Show HN: Fuse – statically typed functional programming language
As I was deciding on the compiler backend, I stumbled upon on it in r/ProgrammingLanguages on reddit. I liked the syntax itself and the fact I can compile the language in the IR of a mini functional language; with a lot of benefits in terms of optimizations. Especially as (strict) pure functional language are notoriously slower than imperative language because of lack of mutations. Allowing me to have a higher-order functional language that has zero cost abstractions.
the_unproven··on Show HN: Fuse – statically typed functional programming language
`Self` isn't the applied type (`List[A]`), rather it's the type constructor of kind `* -> *` constrained by `Functor`. In the map example it gets desugared into:

  fun map[Self: Functor, A, B](self: Self[A], f: A -> B) -> Self[B];
Since `Self` is the unapplied constructor, `Self[B]` just means `Functor[B]` e.g. `List[B]` not `List[A][B]`.

The example you've shown with `SizedFunctor` is not currently supported, as support for associated types is not yet implemented. I got it on the roadmap tho!

the_unproven··on Show HN: Fuse – statically typed functional programming language
Yeah the LSP support is next, my goal is to implement the language server in the fuse itself. At the moment there’s a simple formatter implementation fusefmt: https://github.com/fuselang/fuse/blob/master/examples/fusefm..., you can compile it with fuse and hook-it with your editor.

For example I’ve this config in helix:

  [[language]]                                                                                                                       
  name = "fuse"                                                                                                                      
  scope = "source.fuse"                                                                                                              
  file-types = ["fuse"]                                                                                                              
  injection-regex = "fuse"                                                                                                           
  comment-token = "#"                                                                                                                
  indent = { tab-width = 2, unit = "  " }                                                                                            
  auto-format = true                                                                                                                 
  formatter = { command = "fusefmt" }                                                                                                
                                                                                                                                     
  [[grammar]]                                                                                                                        
  name = "fuse"                                                                                                                      
  source = { git = "https://github.com/stevanmilic/tree-sitter-fuse", rev = "eb5698f4867a4192064e54a92be280f4d2130e03" }
the_unproven··on Show HN: Fuse – statically typed functional programming language
Haskell is a great language with a really advanced type-system, although I found its syntax hard to read at times especially as I was exploring the language at first. On the other hand I really liked how Rust syntax was defined in terms of ADTs, Traits & Methods Impls, with type signatures required for functions. Hence I wished for a similar functional language that has such write-style and type concepts, but stripping away the borrow checker, mutations, etc.
the_unproven··on Show HN: Fuse – statically typed functional programming language
First of all thanks for all the feedback and looking into it, appreciate it!

Yeah GRIN is a great project, it took a lot of debugging and analysis to make it compile 100% especially with monomorphization involved.

I'll look into Unicode support, makes total sense. Didn't scope it in initially. I can fix the site ligatures too, that's a fair remark.

> I don't really understand why you have an IO monad. The language isn't pure - `.exec()` means any function can perform IO actions no matter its type signature - so what's IO really for?

That's a fair point, I still left a place for `.exec()` to happen as un-handled side-effect. But the preference is with using the IO monad as the stdlib is built around it, with `main() -> IO[i32]` as a type signature. As languages evolves I'm planning to build a runtime around IO execution, and build more constraints for handling strict side-effects. However for this initial stage of the language, I left it as a really simple solution.

> Do `impl` additions export? What happens when two libraries add the same function name with different signatures (or just bodies!) to a type's `impl` ?

For now the language doesn't support modules (libraries), I'm planning on adding it. At the moment it's a bit of undefined behavior, as overloading would occur with latest `impl` definition.

> Is currying automatic? It doesn't seem to be, but, eg, the `sum(x: i32, y: i32)` function theoretically could be called as `sum(5)` to create a closure, but this isn't a documented feature if so.

In the type-system it is automatic, and it successfully passes type checker as it's entirely built on top of lambda calculus. But there's an issue with codegen right now. I can def look into it and document it.

the_unproven··on Is Go Duck-Typed?
I just recently found out about these two types of system. It's strange how people (like shown in the article) don't emphasize(know) it when talking about types in languages.

Interestingly, python has included structural subtyping in 3.8[1] as part of the typing module.

[1] https://www.python.org/dev/peps/pep-0544/

the_unproven··on Why events are a bad idea for high-concurrency servers (2003) [pdf]
Events can handle much more connections than a thread based approach. For example nginx is implemented with event-driven architecture: https://www.nginx.com/blog/inside-nginx-how-we-designed-for-...

> NGINX scales very well to support hundreds of thousands of connections per worker process. Each new connection creates another file descriptor and consumes a small amount of additional memory in the worker process. There is very little additional overhead per connection. NGINX processes can remain pinned to CPUs. Context switches are relatively infrequent and occur when there is no work to be done.

> In the blocking, connection‑per‑process approach, each connection requires a large amount of additional resources and overhead, and context switches (swapping from one process to another) are very frequent.

This is their explanation on events vs threading approach. Still, a lot of web servers today use a thread-per-connection which is acceptable since a database(e.g. postgres) performance degrades slowly as more active connections are introduced.[1]

[1] https://brandur.org/postgres-connections

the_unproven··on Goodbye, Clean Code
I also think it's fine to change the code someone wrote. Just because someone wrote it, doesn't mean it's the right way to do it. I often find myself rewriting the code, it's the natural process of code evolution. It just feels that it should be more readable, efficient etc.

Although, if the change is essential or it requires more pair of eyes, I'll just make a PR(MR) and let the people review it.

the_unproven··on A Famous Photo of Chernobyl’s Most Dangerous Radioactive Material (2016)
Reminds of a movie from Andrei Tarkovsky, Stalker. The guy may be the Stalker, leading people to the center of the Zone - the elephant foot in this case.