What is the purpose of the special
property of word?
#2414
Replies: 12 comments 7 replies
-
Hi @kusumotonorio, looking into this now... I remember vaguely how this works. Let me remind myself. |
Beta Was this translation helpful? Give feedback.
-
I think that the way it works is that the word is marked IN: scratchpad DEFER: foo
IN: scratchpad \ foo t "no-compile" set-word-prop
IN: scratchpad : foo ( x -- y ) 1 + ;
IN: scratchpad 1 foo .
2
IN: scratchpad 1 [ foo ] call( x -- y ) .
2
IN: scratchpad : bar ( x -- y ) [ foo ] call( x -- y ) ;
IN: scratchpad 1 bar .
2 That last definition compiles fine, and checks the quotation at runtime even though it's basically a literal, which probably introduces some overhead. Anyway, this is a workaround to get the code working, but then we should do a pass at this to compile the |
Beta Was this translation helpful? Give feedback.
-
You are touching some areas of Factor where assumptions were made a long time ago and we will help push on this with you. I'd love to get one of your multi-methods versions into the core when it's ready! |
Beta Was this translation helpful? Give feedback.
-
As a prank, when I remove the \ mega-cache-lookup "special" remove-word-prop
|
Beta Was this translation helpful? Give feedback.
-
So, does this mean that we need a mechanism for each generic word definition performed by the |
Beta Was this translation helpful? Give feedback.
-
Here are my 2 cents based on my understanding of the compiler internals, I hope that helps and is correct, please disregard otherwise. Generally, the For example, take the word \ nth def>>
[ ... mega-cache-lookup ] I think this is the code which will be executed by the non-optimizing compiler when the word is executed. Since it is a primitive, it will be executed by the VM. The definition quotation of Example: : foo ( x x -- x ) nth ;
\ foo disassemble
---
00007f6774810720: 8905da68defe mov [rip-0x1219726], eax
00007f6774810726: 8905d468defe mov [rip-0x121972c], eax
00007f677481072c: 488d1d05000000 lea rbx, [rip+0x5]
00007f6774810733: e968f4c9ff jmp 0x7f67744afba0 ([ \ nth ~array~ 0 ~array~ inline-cache-miss-tail ])
00007f6774810738: 0000 add [rax], al
00007f677481073a: 0000 add [rax], al
00007f677481073c: 0000 add [rax], al
00007f677481073e: 0000 add [rax], al
! If foo is actually used, the code is modified
0 V{ 42 } foo
---
42
\ foo disassemble
---
00007f6774810720: 8905da68defe mov [rip-0x1219726], eax
00007f6774810726: 8905d468defe mov [rip-0x121972c], eax
00007f677481072c: 488d1d05000000 lea rbx, [rip+0x5]
00007f6774810733: e948ff0200 jmp 0x7f6774840680 (nth)
00007f6774810738: 0000 add [rax], al
00007f677481073a: 0000 add [rax], al
00007f677481073c: 0000 add [rax], al
00007f677481073e: 0000 add [rax], al It looks like that the Nevertheless, it is an error if a quotation containing this word reaches the compiler, as all words which have this in their definition are handled in a special way. |
Beta Was this translation helpful? Give feedback.
-
I have found the solution! I need to change : optimize? ( word -- ? )
{
[ single-generic? ]
[ multi-single-generic? ] ! <-- added
[ primitive? ]
} 1|| not ; |
Beta Was this translation helpful? Give feedback.
-
Aha!!
…On Wed, Jan 6, 2021 at 7:54 PM kusumotonorio ***@***.***> wrote:
I have found the solution!
I need to change the optimize?
<https://docs.factorcode.org/content/word-optimize__que__,compiler.html>
in compiler.factor
<https://github.com/factor/factor/blob/master/basis/compiler/compiler.factor>
.
: optimize? ( word -- ? )
{
[ single-generic? ]
[ multi-single-generic? ] ! <-- added
[ primitive? ]
} 1|| not ;
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2414 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAF5A53Q5KA54YADLZCAP3SYUWBFANCNFSM4VUVWQ7A>
.
|
Beta Was this translation helpful? Give feedback.
-
It is not directly related to the subject, but it seems to be deeply related to it indirectly, so please allow me to continue the story here. I'm currently trying to implement
: (call-next-multi-method) ( method -- )
dup next-multi-method-quot [ call ] [ no-next-multi-method ] ?if ;
\ (call-next-multi-method) t "no-compile" set-word-prop
SYNTAX: call-next-multi-method
current-method get
[ literalize suffix! \ (call-next-multi-method) suffix! ]
[ not-in-a-multi-method-error ] if* ; TUPLE: test-tuple1 ;
TUPLE: test-tuple2 < test-tuple1 ;
TUPLE: test-tuple3 < test-tuple2 ;
MGENERIC: next-method-test ( class -- who-am-i )
MM: next-method-test ( class: test-tuple1 -- who-am-i )
drop "test-tuple1" ;
MM: next-method-test ( class: test-tuple2 -- who-am-i )
call-next-multi-method ;
MM: next-method-test ( class: test-tuple3 -- who-am-i )
drop "test-tuple3" ;
test-tuple2 new next-method-test . I get an error that |
Beta Was this translation helpful? Give feedback.
-
I was able to get The key was to use : (call-next-multi-method) ( method -- )
dup next-multi-method-quot [ call ] [ no-next-multi-method ] ?if ;
USE: stack-checker.transforms
\ (call-next-multi-method) [
[ next-multi-method-quot ] [ '[ _ no-next-multi-method ] ] bi or
] 1 define-transform
\ (call-next-multi-method) t "no-compile" set-word-prop
SYNTAX: call-next-multi-method
current-method get
[ literalize suffix! \ (call-next-multi-method) suffix! ]
[ not-in-a-multi-method-error ] if* ; To be honest, I'm still not sure what I meant by the code I wrote, but it seems to be working well. IN: scratchpad
USE: mm7
TUPLE: test-tuple1 ;
TUPLE: test-tuple2 < test-tuple1 ;
TUPLE: test-tuple3 < test-tuple2 ;
MGENERIC: next-method-test ( class -- who-i-am )
MM: next-method-test ( class: test-tuple1 -- who-i-am )
drop "test-tuple1" ;
MM: next-method-test ( class: test-tuple2 -- who-i-am )
"a subclass of " swap call-next-multi-method append ;
MM: next-method-test ( class: test-tuple3 -- who-i-am )
"a subclass of " swap call-next-multi-method append ;
test-tuple1 new next-method-test .
test-tuple2 new next-method-test .
test-tuple3 new next-method-test .
"test-tuple1"
"a subclass of test-tuple1"
"a subclass of a subclass of test-tuple1"
IN: scratchpad |
Beta Was this translation helpful? Give feedback.
-
As shown above,
If the definition containing : call-next-multi-method-quot ( quot -- )
! This is a word to avoid a compiler error.
drop ;
: (call-next-multi-method) ( method -- )
! The content of this definition is actually replaced and never used.
dup next-multi-method-quot [
call-next-multi-method-quot ! <---
] [ no-next-multi-method ] ?if ;
\ (call-next-multi-method) [
[ next-multi-method-quot ] [ '[ _ no-next-multi-method ] ] bi or
] 1 define-transform
\ (call-next-multi-method) t "no-compile" set-word-prop
SYNTAX: call-next-multi-method
current-method get
[ literalize suffix! \ (call-next-multi-method) suffix! ]
[ not-in-a-multi-method-error ] if* ; But the |
Beta Was this translation helpful? Give feedback.
-
This is great @kusumotonorio! When you get a moment, can you comment on your latest and greatest version and what kind of improvements it has over the current |
Beta Was this translation helpful? Give feedback.
-
I'm working on errors that a definition containing the primitive word
mega-cache-lookup
cannot be compiled.The
mega-cache-lookup
is instack-checker.known-words
and thespecial
property seems to be set to[ \ mega-cache-lookup do-not-compile ]
. I suspect that my problem may have something to do with this.What is the purpose of the
special
property?Why do the definitions of method not raise a compiler error when it contains this word, but my code that mimics it does?
Beta Was this translation helpful? Give feedback.
All reactions