It’s like there’s a reason why APL (and successors) isn’t widely popular :stuck_out_tongue:
(although, from what I understand, the requirement for an enormous keyboard with multiple otherwise-superfluous buttons was actually as much of a barrier as the ultra-terse syntax)
Yeah, “you have to buy special hardware to use this language” is a deal killer
I tested it, it works well, thanks. It would be nice, if this macro could be included in racket/class. But I don’t know whether it is a good or bad idea in Racket. (define/public (pay)
(a-high-order-function (& get-price)))
Fear not - these days, you can buy one of these: https://www.youtube.com/watch?v=nidnvlt6lzw
In Factor (from a friend): 1 3000 [a,b] [ number>string [ CHAR: 2 = ] count ] map-sum
@soegaard2 After reading this paper, I found the “higher-order methods” is an open issue in PLT Scheme. > In a similar vein, the class system prohibits an internal reference to a method that > is not in an application position (i.e., as a method call). Occasionally, we would like > to pass a method as a first-class value to functionals such as map. In this case, the > class macro could easily convert the method to a closure over this; we instead force > programmers to wrap the method with a lambda so that the closure allocation is more > apparent. We may reconsider this design decision.
Then there is another open issue which is also very annoying… > The class forms’s distinction between initialization arguments and fields makes > explicit that values used only for initialization need not be stored in the object. Nevertheless, > initialization arguments often turn into fields, and there seems to be no advantage > in forcing programmers to explicitly designate such conversions; merely referencing > an initialization argument from a method should be enough to convert it to a field. > Automatic conversion, however, requires expanding all subexpressions when expanding > a class form, but the class form needs to expand sub-expressions differently for > fields than for initialization arguments. In other words, our macro technology affects > our language design (in much the same way that parsing and type-checking concerns > sometimes influence the outcome of other language design decisions). That means, for example, if we define a class like this: (class object%
(init size)
(define current-size size) ; <--- note the field name
(super-new)
(define/public (get-size)
current-size)
(define/public (grow amt)
(set! current-size (+ amt current-size)))
(define/public (eat other-fish)
(grow (send other-fish get-size))))
We can not name the field be size
, we must add some prefix, e.g. current-
If the racket/class support “Automatic conversion”, then we can eliminate the field current-size
directly.
you can use init-field
for this
That is great! Thanks!
The point they’re making in the paper is that the init
/init-field
distinction shouldn’t be required.
@samth I think init-field
is good enough, why we need init
as well?
That’s what @samth said: there probably shouldn’t be init
.
Yes, maybe some one use these init arguments in field definition which is a function call…
If you don’t want to use the APL or Wingdings alphabets, there is also this: https://en.wikipedia.org/wiki/Q_(programming_language_from_Kx_Systems)
I have a question about mixin, see following code: (define core-interface (interface () eat))
(define core-mixin
(mixin () (core-interface)
(super-new)
(define/public (eat)
(displayln "core eat"))
(define/public (play)
(displayln "core play"))
))
(define extension-interface (interface () eat play))
(define extension-mixin
(mixin (core-interface) (extension-interface)
(super-new)
(define/override (eat)
(displayln "extension eat"))
(define/override (play)
(displayln "extension play"))
))
(define extension-size% (extension-mixin
(core-mixin
object%)))
; mixin: method was referenced in definition, but is not in any of the from-interfaces
; method name: play
; from-interfaces:
; #<interface:core-interface>
; [Due to errors, REPL is just module language, requires, and stub definitions]
core-mixin
has two public methods and it implements a one method interface, extension-mixin
inherit core-mixin
and override these two methods. Why failed? Very thanks.
because core-interface
doesn’t include play
so you can’t override it
Why core-interface
must include play
?
If I am a user of core
, I don’t want play
you can only override play
if it’s in the interface you inherit from
I don’t quite understand that since play
is public and the combination of the mixing, i.e. (extension-mixin (core-mixin object%)
only involved classes, why we must check interface?
It would be nice, if there are some keyword something like: define/override
<— this one for override class define/implement
<— this one for implement interface
That’s what the mixin
form does. If you don’t want that check, you can just use lambda
and class
instead of mixin
So the conclusion is: if we want use mixin
form, we need to define one or more interfaces for each mixin
and let the union of these interfaces include all the public methods of the mixin
as much as possible.
Note that there are various functions that compute an interface
Like class->interface
It occurred to me that if a class has public methods, then they must belong to some interface implicit, so write it explicit.
the point of the mixin
form is that the specification is those two lists of interfaces. in your program, if you remove the definition of play
from core-mixin
, you get a runtime error when creating the class.
even though you followed the requirements of the interfaces listed.
I and add the play
to core-interface
, and removed the definition in the core-mixin
(define core-interface (interface () eat play))
(define core-mixin
(mixin () (core-interface)
(super-new)
(define/public (eat)
(displayln "core eat"))
))
(define extension-interface (interface () eat play))
(define extension-mixin
(mixin (core-interface) (extension-interface)
(super-new)
(define/override (eat)
(displayln "extension eat"))
(define/override (play)
(displayln "extension play"))
))
Then compile success, but runtime failed when creating class as you said (define extension-size% (extension-mixin
(core-mixin
object%)))
; class*: missing interface-required method
; method name: play
; class name: ...ce-implement-sep.rkt:21:2
; interface name: core-interface
; [Due to errors, REPL is just module language, requires, and stub definitions]
That paper also mentioned that > Like most class systems, the PLT Scheme system conflates implementation inheritance > and interface inheritance. That is, a subclass automatically implements any interface > that its superclass implements. We are in a good position to try detaching interface > inheritance from subclassing, but we have not yet explored that possibility. Has this open issue been fixed in current Racket?
That’s great, but this function seem useless when we using fully-mixin programming? Because there is no class at all.
I would not describe that as an open issue; it’s a possibility for new design in that direction. Some research was done in this direction, but it never became part of Racket.
Thanks @samth
I found a corner case of class instantiation: (define core-interface (interface () get-state))
(define core-mixin
(mixin () (core-interface)
(super-new)
(init state)
(define current-state state)
(define/public (get-state)
current-state)
))
(define extension-interface (interface () get-state))
(define extension-mixin
(mixin (core-interface) (extension-interface)
(super-new)
(init state)
(define current-state state)
(define/override (get-state)
(displayln (super get-state))
current-state)
))
(define extension% (extension-mixin
(core-mixin
object%)))
(define extension-instance (new extension% [state 10] [state 100]))
(send extension-instance get-state)
>> 100
>> 10
In this case, we use two init arguments state
with the same name. So the init arguments are order sensitive, although it must use name.
Yes, that’s correct (the details are here https://docs.racket-lang.org/reference/objcreation.html)
And another usage of undefined
:grin: > All fields in the newly created object are initially bound to the special <https://docs.racket-lang.org/guide/void_undefined.html%7C#<undefined>> value
Oh, that’s what trait does, I just realized.
factor is a very cool language