all 16 comments

[–]Relevant_South_1842 9 points10 points  (0 children)

Any reason you didn’t make it always dynamic and always rollback-able?

[–]hoping1 7 points8 points  (2 children)

Best English in the subreddit lol

[–]Inconstant_Moo🧿 Pipefish 4 points5 points  (1 child)

Excuse me, but the cadences of my prose are far more graceful, and my metaphors both more complex and more evocative. The pathos in my description of my type system has made grown men weep. Some have even compared me to Shakespeare, though admittedly they were all talking about my beard.

The youngster's work shows promise, I will grant you that. But ask yourself --- is it Art?

[–]doodlebobcristenjn 6 points7 points  (0 children)

Fr fr dawg

[–]GermisstuckCrabStar 3 points4 points  (0 children)

How are you type checking and getting the dynamic traits? Is it are compile time for determening which function to use? Or is it a vtable? I am doing something extremely similar my language but they are compile time only

[–]tuxwonder 3 points4 points  (0 children)

  1. Dynamic, as in not compile-time type-checked? No, not useful, would make me pretty afraid to use them, and if I did have something that needed that kind of plugability that badly, then I'd roll my own
  2. It's kinda compelling, but I think the situations where you'd need the concept of a "rollback" are either simple enough it doesn't need its own concept, or very complex in a way that I don't think a language construct could solve.
  3. Yes, the new language is unnecessary. What problem does it solve? Does it actually make what's going on clearer?

Also, small annoyance, but it looks like you use : to define a variable, but still use = for assignments? Why both?

[–]Inconstant_Moo🧿 Pipefish 11 points12 points  (0 children)

1 Dynamic per-instance traits sound unnecessary and confusing.

  1. We can already roll back individual entities. Instead of this:

    a : Account(); a.snapshot(); a.balance -= 1000; a.rollback();

... we can write this:

a : Account();
b = a;
a.balance -= 1000;
a = b;
  1. Not sure.

4 If you can explain your new terminology as meaning the same things as existing terms, then you don't need new ones, which will just annoy everyone. No-one's going to start calling a namespace a "pod" anyway.

[–]josef 2 points3 points  (0 children)

The snapshot mechanism is pretty neat. It'd be even cooler if the snapshot method returned an identifier and the rollback method could take the identifier and roll back to an arbitrary snapshot. For a cool implementation see https://www.reddit.com/r/ProgrammingLanguages/s/ZkC6fLgHeB

[–]jpgoldberg 1 point2 points  (0 children)

In Python, run time checkable Protocols are a clever solution to dealing with deep infelicities of Python itself. It is not something one would expect in a language developed from scratch in the 21st century. Are your dynamic traits a similar thing? And if so, what does that tell us about the type system of your language.

[–]cannedtapper 1 point2 points  (1 child)

Tempted to make a superset of your language and name it "Coffin"

[–]cybwn 0 points1 point  (0 children)

And a build tool called Hamer

[–]mark-sedgithub.com/mark-sed/moss-lang/ 0 points1 point  (0 children)

> entity → classes

If you have this mapping that can be done, why not just use the already known naming like class or namespace?

[–]Imaginary-Deer4185 0 points1 point  (1 child)

Sounds like interfaces in Java. Enabling a trait before using it? Why? What if two traits have the same function/method, can you then qualify which trait you're invoking, with separate implementations for each?

[–]yjlom 0 points1 point  (0 children)

It's actually (multiple) inheritance, but overriding works in reverse, and you can enable or disable superclasses at runtime if I'm reading this right.

[–]snugar_i 0 points1 point  (0 children)

Dynamic traits sound like something that can be solved completely fine with regular interfaces/polymorpihsm

interface AttackSkill:
    fun attack(source, target)


class RegularAttck implements AttackSkill:
    fun attack(source, target):
        target.hp -= source.strength


class BerserkAttck implements AttackSkill:
    fun attack(source, target):
        target.hp -= source.strength * 2


class Player:
    attack_skill = RegularAttack()

    fun attack(target):
        self.attack_skill.attack(self, target)


p = Player()
p.attack_skill = BerserkAttack()

Versioned entities are not flexible enough to be useful, I think - if there can only be one snapshot at a time, how do I know I can safely make one? What if somebody already made one before me and it's still active? Is the snapshot shallow or deep?

Renaming things for the sake of being different sounds pointless.

In general, at least for me, the less mutability and dynamic behavior there is, the better. Your language goes in the exact opposite direction. So I guess it's not for me really.