jcoo092
2020-7-17 09:06:16

It’s like there’s a reason why APL (and successors) isn’t widely popular :stuck_out_tongue:


jcoo092
2020-7-17 09:08:11

(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)


notjack
2020-7-17 09:11:19

Yeah, “you have to buy special hardware to use this language” is a deal killer


chansey97
2020-7-17 09:11:32

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)))


soegaard2
2020-7-17 09:13:26

Fear not - these days, you can buy one of these: https://www.youtube.com/watch?v=nidnvlt6lzw


badkins
2020-7-17 14:37:29

In Factor (from a friend): 1 3000 [a,b] [ number>string [ CHAR: 2 = ] count ] map-sum


chansey97
2020-7-17 16:19:55

@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.


chansey97
2020-7-17 16:28:24

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.


samth
2020-7-17 16:30:05

you can use init-field for this


chansey97
2020-7-17 16:34:47

That is great! Thanks!


samth
2020-7-17 16:36:07

The point they’re making in the paper is that the init/init-field distinction shouldn’t be required.


chansey97
2020-7-17 16:40:22

@samth I think init-field is good enough, why we need init as well?


sorawee
2020-7-17 16:41:24

That’s what @samth said: there probably shouldn’t be init.


chansey97
2020-7-17 16:43:53

Yes, maybe some one use these init arguments in field definition which is a function call…


gknauth
2020-7-17 19:03:50

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)


chansey97
2020-7-17 19:30:00

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.


samth
2020-7-17 19:31:42

because core-interface doesn’t include play so you can’t override it


chansey97
2020-7-17 19:32:11

Why core-interface must include play ?


chansey97
2020-7-17 19:32:47

If I am a user of core, I don’t want play


samth
2020-7-17 19:32:50

you can only override play if it’s in the interface you inherit from


chansey97
2020-7-17 19:36:43

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?


chansey97
2020-7-17 19:41:36

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


samth
2020-7-17 19:41:56

That’s what the mixin form does. If you don’t want that check, you can just use lambda and class instead of mixin


chansey97
2020-7-17 19:47:56

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.


sorawee
2020-7-17 19:49:22

Note that there are various functions that compute an interface


sorawee
2020-7-17 19:49:35

Like class-&gt;interface



chansey97
2020-7-17 19:54:29

It occurred to me that if a class has public methods, then they must belong to some interface implicit, so write it explicit.


samth
2020-7-17 19:56:38

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.


samth
2020-7-17 19:56:51

even though you followed the requirements of the interfaces listed.


chansey97
2020-7-17 20:03:53

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]


chansey97
2020-7-17 20:06:43

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?


chansey97
2020-7-17 20:10:25

That’s great, but this function seem useless when we using fully-mixin programming? Because there is no class at all.


samth
2020-7-17 20:12:38

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.


chansey97
2020-7-17 20:13:47

Thanks @samth


chansey97
2020-7-17 20:22:06

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) &gt;&gt; 100 &gt;&gt; 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.


samth
2020-7-17 20:24:09

Yes, that’s correct (the details are here https://docs.racket-lang.org/reference/objcreation.html)


chansey97
2020-7-17 20:28:21

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#&lt;undefined>> value


chansey97
2020-7-17 21:09:30

Oh, that’s what trait does, I just realized.


samdphillips
2020-7-17 23:14:09

factor is a very cool language