Live data from Hacker News

Tao: A statically-typed functional language

github.com

71–80 of 98 posts

Re: Tao: A statically-typed functional language

#71

Hey, author here. I definitely didn't expect to see Tao on Hacker News. As is probably obvious, the language is extremely early in its life, and it's not practical to write anything but trivial examples in it yet. Please don't judge!

I'm curious how you implement associated types and equivalences between them. In the most general case, this allows encoding an arbitrary finitely-presented monoid in the type system, and the word problem on finitely-presented monoids is undecidable. However, you mention your type checker is Turing-complete.

Re: Tao: A statically-typed functional language

#72
post #63

Earlier quoted context omitted.

> Curious how Tao is pushing the limits on that front? I don't want to put emphasis on "pushing the limits" because I'm still very new to language design and mostly self-taught. There are bigger and better languages pushing the envelope further than Tao! That said, I've been experimenting with: - Expressing totality and type inhabitance in the type system - Effect systems (including user-defined effects, effect handl…

would you mind explaining the linked code?

The code is a bit of a gimmick, not really the sort of thing you'd have in a real program. It's just there to demonstrate that the compiler doesn't need explicitly telling which typeclasses associated types correspond to. That said:

    fn show_negative A : A -> Str where
        A  (----a)->show
This is a function, called `show_negative`, that is generic over a type, `A`. The function takes an instance of `A` and returns a `Str` (string).

In terms of implementation, the function is quite simple: it just negates the input value a bunch of time and then `show`s it as a string using the `Show` typeclass (equivalent to Haskell's `show`: https://hackage.haskell.org/package/base-4.16.1.0/docs/Prelu...).

Arithmetic operations such as negation are defined using typeclasses. Here's the definition of `Neg`:

    class Neg =
        => Output
        => neg : Self -> Self.Output
This means that types that can be negated must provide two things: an output type produced when they're negated, and a function that actually performs the negation. For example, `Nat` (natural number) looks like:

    member Nat of Neg =
        => Output = Int
        => neg = fn x => (implementation omitted because it's a built-in intrinsic)
i.e: when you negate a `Nat`, you get an `Int`.

The `where` clauses on the `show_negative` just constrains the output type of negating the `A` in such a way that its output type is also constrained, in a chain, with the final type in the chain being `show`-able.

Re: Tao: A statically-typed functional language

#73

Hey, author here. I definitely didn't expect to see Tao on Hacker News. As is probably obvious, the language is extremely early in its life, and it's not practical to write anything but trivial examples in it yet. Please don't judge!

I'm curious how you implement associated types and equivalences between them. In the most general case, this allows encoding an arbitrary finitely-presented monoid in the type system, and the word problem on finitely-presented monoids is undecidable. However, you mention your type checker is Turing-complete.

Yep, this is the case: the type-checker allows arbitrary computation to occur at compilation time. You can see some of that here, where I've implemented peano arithmetic/addition/multiplication/branching using the type system: https://github.com/zesterer/tao/blob/master/examples/type-as... . I've not yet had the time or mental fortitude to implement something more non-trivial like N-queens or a Brainfuck interpreter, but perhaps eventually!

Re: Tao: A statically-typed functional language

#74

Hey, author here. I definitely didn't expect to see Tao on Hacker News. As is probably obvious, the language is extremely early in its life, and it's not practical to write anything but trivial examples in it yet. Please don't judge!

Tao looks super cool, and similar to the kind of language I'd personally make if I decided to create one. Kudos for actually implementing yours!

Some specific questions about the language design: - Does your flavor of algebraic effects allow distinct effects of the same type (e.g. two separate int-valued `State`s)? I haven't seen anyone talk about this, but it seems like a potential problem with effects.

- Do you have plans for making pattern matching extensible? I've thought a lot about how this could be possible with optics (the FP construction), but haven't found a nice solution yet.

Re: Tao: A statically-typed functional language

#75
post #74

Hey, author here. I definitely didn't expect to see Tao on Hacker News. As is probably obvious, the language is extremely early in its life, and it's not practical to write anything but trivial examples in it yet. Please don't judge!

Tao looks super cool, and similar to the kind of language I'd personally make if I decided to create one. Kudos for actually implementing yours! Some specific questions about the language design: - Does your flavor of algebraic effects allow distinct effects of the same type (e.g. two separate int-valued `State`s)? I haven't seen anyone talk about this, but it seems like a potential problem with effects. - Do you hav…

> Does your flavor of algebraic effects allow distinct effects of the same type

Could you give an example of what you mean by this? Multiple effects can be combined together (although I'm still working on handlers for multiple effects), for example:

    effect console = input + print

    fn greet_user : console ~ () = {
        print("Please enter your name:")!;
        let name = input!;
        print("Hello, " ++ name)!;
    }
> Do you have plans for making pattern matching extensible?

I have no plans as of yet. Extensible pattern-matching seems to me to be quite hard to unify with exhaustivity. Tao supports most of the patterns that Rust/Haskell supports.

Re: Tao: A statically-typed functional language

#76

Somewhat familiar with FP and enjoy some of its benefits in my projects but I haven’t really used a full blown FP language like Haskell. What exactly is a type class? I haven’t found an explanation that makes a lot of sense to me. I think at one time I believed them to be some kind of contract like an interface in a OO language. Can someone explain?

One of the things that's hard to follow is that people conflate typeclasses and typeclass instances.

So, the typeclass itself is like an interface, but rather than having classes that implement that interface directly, you have typeclass instances which are like an adapter between a value (struct) and the interface - or like a virtual function table. You know how a class instance is essentially a struct + a (pointer to a) virtual function table? Imagine making those two pieces more distinct in code - the typeclass instance is the stanadlone virtual function table.

So your object state is more exposed - you can't really have private fields in this paradigm since your state is just a struct value. But it's clearer what's what, and it's much easier to adapt types to interfaces even when the authors didn't know about each other, since the typeclass instance can be defined separately from both the typeclass and the value type (although there are possible inference problems with this). So lots of secondary cross-cutting functionality problems where OO languages tend to end up with an ad-hoc type registry (e.g. serialization or database mapping - just look at what projects like jackson-datatype-joda or joda-time-hibernate have to do to get themselves registered) are easier to solve in this model.

Re: Tao: A statically-typed functional language

#77
post #74

Earlier quoted context omitted.

Tao looks super cool, and similar to the kind of language I'd personally make if I decided to create one. Kudos for actually implementing yours! Some specific questions about the language design: - Does your flavor of algebraic effects allow distinct effects of the same type (e.g. two separate int-valued `State`s)? I haven't seen anyone talk about this, but it seems like a potential problem with effects. - Do you hav…

> Does your flavor of algebraic effects allow distinct effects of the same type Could you give an example of what you mean by this? Multiple effects can be combined together (although I'm still working on handlers for multiple effects), for example: effect console = input + print fn greet_user : console ~ () = { print("Please enter your name:")!; let name = input!; print("Hello, " ++ name)!; } > Do you have plans for…

I think GP is referring to having two effects, like State1 and State2, both of which allow for stateful effects on int references, and then being able to handle the effects uniquely for each effect. I think the underlying type theoretical question would be are Tao’s effects nominally vs. structurally typed.

A more practical example would be having two state-like effects for use as different allocation/deallocation strategies.

Re: Tao: A statically-typed functional language

#78

Earlier quoted context omitted.

Why not just require parents for nested cases? IMO this is fairly unambiguous, even to people unfamiliar with a particular language.

In a previous revision of the language, I did! ( https://github.com/zesterer/tao/tree/old ). I decided against it because, in short, I find the trailing delimiters to be quite ugly. Because this is purely a personal project, I'm thankfully not constrained by such mundane concerns as "ergonomics" (unless such concerns relate to me while I'm working with it). I think Pythonic syntax is probably the way to go long-term…

Personally I'm a big fan of Julia's syntax here. Indentation-insensitive with the use of the word "end" as the terminator for all types of block. In practice you can lay it out like Python, and the "end"s help you keep track when e.g. you need to place a single expression after some deeply-nested blocks.

Re: Tao: A statically-typed functional language

#80

Earlier quoted context omitted.

> Does your flavor of algebraic effects allow distinct effects of the same type Could you give an example of what you mean by this? Multiple effects can be combined together (although I'm still working on handlers for multiple effects), for example: effect console = input + print fn greet_user : console ~ () = { print("Please enter your name:")!; let name = input!; print("Hello, " ++ name)!; } > Do you have plans for…

I think GP is referring to having two effects, like State1 and State2, both of which allow for stateful effects on int references, and then being able to handle the effects uniquely for each effect. I think the underlying type theoretical question would be are Tao’s effects nominally vs. structurally typed. A more practical example would be having two state-like effects for use as different allocation/deallocation st…

Tao's effects are nominally typed, so there's no way to accidentally mix them up in the way I assume you're describing. For example:

    # Define a new effect that yields to the caller
    effect yield A = A => ()

    # A generator that emits numbers
    def one_two_three : yield Nat ~ () = {
        yield(1)!;
        yield(2)!;
        yield(3)!;
    }

    # Print the numbers to the console
    def main : io ~ () = {
        one_two_three
            handle yield Nat with n => print(n->show)!
    }
Post reply on HN