Relating the side note: I was wrong when I said I made a self-modifying function, I had just modified a function from another one. Interesting use of pop and push, I'll play a little with it later.
To the topic at hand:
We've said keywords could serve three purposes:
1. as one-time-with-no-previous-registration-required flags
2. as named parameters in functions
3. as hash keys
So, real applications that use keywords?
My previous posted _choose-method function is a good example: you want to
decide something inside a function and you just need a flag, no value required.
One option would be to leave it with a number and document it:
Code: Select all
(define (_choose-method (_method 0)) ...)
But if one wanted to make the code more self-describing, could create a couple
of constants:
Code: Select all
(constant 'SAVE_IN_KEYWORDS_CONTEXT 0)
(constant 'SAVE_IN_CALLING_CONTEXT 1)
(define (_choose-method (_method SAVE_IN_KEYWORDS_CONTEXT)) ...)
Using keywords there no need to define the constants and code gets
self-documented:
Code: Select all
(define (_choose-method (_method .save-in-keywords-context))
(if (true? .save-in-keywords-context) ...))
As you can see, for this use case, is a matter of practicallity, just a
"syntactic convenience" as you explain in the manual for the let form.
Another example, I have a set of PHP functions like these:
Code: Select all
public function select($query, $index_by = null) {
public function select_all_by_pk() {
public function select_all() {
public function select_all_with_foreign_keys()
public function select_one($id) {
public function select_field($id, $field) {
public function select_by_field($field, $value) {
If I were to program these in newlisp, I would like to have just one select
function, and be able to say:
Code: Select all
(select query .index-by-title)
(select .all-by-primary-key)
(select .all)
(select .all-with-foreign-keys)
(select id)
(select id .field-title)
(select field .by-field)
And another one: when you don't need to mix options, like in the function timer, you could use keywords:
Code: Select all
; so
syntax: (timer sym-event-handler | func-event-handler num-seconds [int-option])
; could become
syntax: (timer sym-event-handler | func-event-handler num-seconds [.real-time | .user-time | .profiling-time])
For the second use case, as named parameters, Lutz shown this:
Code: Select all
(define-macro (foo:foo)
(local ($len $width $height)
(bind (args) true)
(println "len:" $len " width:" $width " height:" $height)
))
(foo ($width 20) ($height 30) ($len 10)) ;=> len:10 width:20 height:30
With keywords it would be like this:
Code: Select all
(define-macro (foo:foo)
(println "len: " .len " width: " .width " height: " .height))
; and called like this:
(foo .width 20 .height 30 .len 10) ; -> len: 10 width: 20 height: 30
And there will not be any global variable, just a property name on a property
list.
For the third case, as hash keywords, this is what we currently have:
Code: Select all
(new Tree 'Myhash)
(Myhash "var" 123) ; create and set variable/value pair
(Myhash "var") → 123 ; retrieve value
With keywords:
Code: Select all
(new tree 'MyHash)
(MyHash .title "The Razors Edge")
(MyHash .year 1990)
(MyHash .artist "AC/DC")
; still allow any string to be a hash symbol
(MyHash "rating" .10/10) ; and allow a keyword to be a value
; look how self-describing is the .10/10 keyword
I don't think it's much of an improvement, besides saving three keystrokes. I think is just and extension of the two previous uses: as a flag holding a meaning, and as a symbol holding a value.
I think the benefit of this kind of type is that it can hold a value: itself, which is just another way of saying "true", or a specific value like in named parameters. And at the same time be self describing.
In my first example one has to resort to cryptic numbers or set constants if self description is desired.
In the .10/10 example, I'm saying with just one keyword: "I'm giving a value of 10 to this CD. Scale goes up to 10."
Note: Maybe I'm blurring the waters with this one. It was a last-minute thought.
Translation: I haven't thought well the last one.
As for the implementation details, I got several doubts. My only certainty is that our keywords should not live all mixed up in a special context called Keywords, but be part of the context they're defined.