ozra / onyx-lang

The Onyx Programming Language
Other
95 stars 5 forks source link

Allow Prime (Apostrophe in Reality) Signs at End of Identifiers #95

Open ozra opened 7 years ago

ozra commented 7 years ago

I still feel an urge to allow apostrophes (mimicking primes) at the end of identifiers. I've wanted that since the beginning, but put it of again and again because of fear of confusion when reading code - but I think it's very moot!

The prime is used for (grave generalizations here) "it's like x, but processed a step more", or "it's similar to x but not quite". The most common case is derivations. This for both values and functions.

The "fear" is (un)founded in that Onyx currently has two uses of '. One common, the other not yet that "known":

Now, finally: on to the issue at hand, damn it.

close = a-stream-of-financial-close-price-data-series("sourced-some-where")
close-50 = close.ema 50
close-50' = close-50.roc 14
close-50'' = close-50'.roc 14

plot close-50, Blue, scale: Relative, axis: Right
plot close-50', Orange, scale: Relative
plot close-50'', color: Green, scale: Relative
type Foo
   @updates = 0

   update() ->   -- the publicly commonly used method, but is just a wrapper for the meat
      @updates += 1
      update'
      fire-rockets-in-celebration

   update'() -> abstract   -- implements the real guts in the sub-types
end

type Bar < Foo
   update'() -> do-important-updating-for-Bar

type Qwo < Foo
   update'() -> do-important-updating-for-Qwo

for obj in [ Bar(), Qwo() ]
   obj.update

Of course, they should probably also be protected, I just avoided it, to not cause confusion regarding this issue (update'*() -> do-stuff, cough, cough)

This pattern is seen everywhere in code - sometimes with crazy naming schemes, like do_the_thing and do_the_thing_without_this_and_that as the main function, wrapped by the do_the_thing.

Instead, making the-super-func and the-super-func' idiomatically popular naming schemes in Onyx would be a great gain in that aspect imo. When you want the meat of the functionality, and there are several "gateway"-functions of different type specializations, you know how to find the real deal - it's named the-muddafuckin-func-name'() ->

I have not yet found a suitable unicode point that represents it nicely, and being implemented in popular fonts.

Well, that was that.

Sod-Almighty commented 7 years ago

This explanation is difficult to follow. And even after following it, I don't see the point. The ' suffix is used in mathematics because there is no implied sense of the passage of time:

a = a + 1    -- total nonsense in mathematical terms

a' = a + 1   -- the suffix is needed to indicate a change is occurring, rather than an assertion

In programming, this is not needed:

value = some-calculation
value = value.some-further-processing
puts value

In the case of wrapped functions, as in your second example, I personally suffix an underscore. Ruby example:

def print(hash)
  print_(hash, 0)
end
private def print_(hash, indent_level)
  hash.each do |k,v|
    case v
      when Hash, Array
        puts "%s: " % k
        print_(v, indent_level+1)
      else
        puts "%s: %s" % [k,v]
    end
  end
end

Also, sometimes it's better to make it a nested function, or an anonymous function. Speaking of which, it'd be handy to be able to recurse an anonymous function. We'd need a keyword (a la super) or some kind of lexical reference, that means "the current function":

->(){
  .()     # infinite recursion
}.()
ozra commented 7 years ago

In programming, this is not needed

Those derived values are all used subsequently. The imperative mutating example you show doesn't counter that use example. I write zillions of lines of code like that in series analysis, where there are often derived series from others with slight variations that occur again and again, and where tacking on name-suffixes makes little sense or help.

In the case of wrapped functions, as in your second example, I personally suffix an underscore.

That's a valid approach. I don't think it looks better or clearer though.

Further discussion on anon self reference should go into it's own issue.

Sod-Almighty commented 7 years ago

derived series from others with slight variations that occur again and again

Then I'm afraid I don't really understand the problem we're trying to solve.

ozra commented 7 years ago

Exactly what I described in the examples? :-P

ozra commented 7 years ago

Yet other examples where "pretty much the same thing" is needed, the very idiomatic "assign to local to lock the state for flow inference":

type Foo
   @foo Int32?  'get 'set
   @bar Str?  'get 'set

   do-some-shit() ->
      if foo' = foo && bar' = bar
         do-stuff-with foo', bar'
         foo'.more-stuff bar'
      end
   end
end

Not necessarily an argument for ' specifically, but for the ability to have a character to de-facto signify such uses.

Sod-Almighty commented 7 years ago

I still don't understand the problem we're trying to solve here.

ozra commented 7 years ago

Get a good way of naming the temp, derivative or main-impl, etc. commonly reoccurring constructs where a new var/func is needed, but it's not really something that reasonably should be named differently.

Like you solve it with foo_. (That is common for initialization lists in C++ also, and sometimes instance vars - different style guides). So simply something that does have such a connotation (which prime has) rather than using, for instance, underscore. I think it would be a helpful feature for some idiomatic patterns.

ozra commented 7 years ago

Btw, the real prime character () isn't supported in any of the popular monofonts (when I tried on google fonts) :-(

ozra commented 7 years ago

Well, this will definitely be a go. It's super-useful. And some syntax to do auto-var-naming: if (foo?.stuff?.here?)' and (qwo())' then use(foo-stuff-here', qwo')

Sod-Almighty commented 7 years ago

Auto-vars might actually be pretty useful.