Discuss Scratch

  • Discussion Forums
  • » Advanced Topics
  • » If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null? [RSS Feed]
-Io-
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

Just curious, is there a way to make a block which directly outputs the value said by it to the JSON?

Like, you have something like:
(join (item (1 v) of [list v]) (letter (0) of (raw [snip deleteLine:ofList: snip scratchblocksv2 can't escape brackets] :: grey)))
aka
[0,
0,
[["concatenate:with:", ["getLine:ofList:", 1, "list"], ["letter:of:", 0, ["raw:", "[\"deleteLine:ofList:\", 1, \"list\"]"]]]]]
But when ran it would run as:
[0,
0,
[["concatenate:with:", ["getLine:ofList:", 1, "list"], ["letter:of:", 0, ["deleteLine:ofList:", 1, "list"]]]]]
aka
(join (item (1 v) of [list v]) (letter (0) of {delete (1 v) of [list v]}))

And maybe make it so when the project is saved it turns into the real thing you put into the raw block.
TheLogFather
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

TheLogFather wrote:

Anyway, let's make it look even worse, and nest them:
say (letter {set [var1 v] to (join [a] (letter {set [var2 v] to (join [b] (letter {set [var3 v] to (join [c] (letter {set [var4 v] to [d]} of []))} of []))} of []))} of [])
Oh dear… I must've been getting rather tired when I wrote that, since I look at it now, with fresh eyes, and it's quite obviously going to execute in the wrong order – the “set var4” will evaluate first.

Ah well, it was just a bit of fun…

BookOwl
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

While direct custom reporters seem impossible using this technique, I think that have created the best workaround yet.
https://scratch.mit.edu/projects/109467434/
joefarebrother
Scratcher
500+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

What happens when the hacked stack block is something that pauses the script, for example wait () secs, or, more interestingly, broadcast and wait?
-Io-
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

joefarebrother wrote:

What happens when the hacked stack block is something that pauses the script, for example wait () secs, or, more interestingly, broadcast and wait?
liam thought of it before anyone
https://scratch.mit.edu/projects/109268046/
https://scratch.mit.edu/projects/109337946/
Hardmath123
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

TheLogFather wrote:

TheLogFather wrote:

Anyway, let's make it look even worse, and nest them:
say (letter {set [var1 v] to (join [a] (letter {set [var2 v] to (join [b] (letter {set [var3 v] to (join [c] (letter {set [var4 v] to [d]} of []))} of []))} of []))} of [])
Oh dear… I must've been getting rather tired when I wrote that, since I look at it now, with fresh eyes, and it's quite obviously going to execute in the wrong order – the “set var4” will evaluate first.

Ah well, it was just a bit of fun…

You also just re-invented monads, so that's something to be proud of.
-Io-
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

Hardmath123 wrote:

TheLogFather wrote:

TheLogFather wrote:

Anyway, let's make it look even worse, and nest them:
say (letter {set [var1 v] to (join [a] (letter {set [var2 v] to (join [b] (letter {set [var3 v] to (join [c] (letter {set [var4 v] to [d]} of []))} of []))} of []))} of [])
Oh dear… I must've been getting rather tired when I wrote that, since I look at it now, with fresh eyes, and it's quite obviously going to execute in the wrong order – the “set var4” will evaluate first.

Ah well, it was just a bit of fun…

You also just re-invented monads, so that's something to be proud of.
Hey, I did it first
scratchyone
Scratcher
100+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

This is really nice!

Self-Advertisment:
I just finished an editor that gets a scratch project from url, lets you edit the json, and then rezips it automatically.
https://scratchyone.github.io/sb2edit/

TheMonsterOfTheDeep wrote:

I've been trying to solve some of the issues with these “inline,” so to speak, functions/blocks/whatever with broadcasts.

Here are the results I have gotten so far:
When simply setting the arguments (variables arg1 and arg2) to constants, I've been able to successfully call the broadcast block inline twice in a row. (Although, I haven't tested it with “return” in variable form - I have only tested it with “return” in list form.)
When setting the variable arg1 to the return value and calling the broadcast a second time inline, the project always got stuck in an infinite loop (somehow? maybe I should look at how it's being interpreted…) no matter if I set the variable through a return value as a list or a variable.

In any case, I really need to get to bed, so I can't continue my experiments right now.
Interesting. When I tested, it ran, but it ran after running the rest of the block.
_TigerJack21_
Scratcher
83 posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

scratchyone wrote:

This is really nice!

Self-Advertisment:
I just finished an editor that gets a scratch project from url, lets you edit the json, and then rezips it automatically.
https://scratchyone.github.io/sb2edit/

TheMonsterOfTheDeep wrote:

I've been trying to solve some of the issues with these “inline,” so to speak, functions/blocks/whatever with broadcasts.

Here are the results I have gotten so far:
When simply setting the arguments (variables arg1 and arg2) to constants, I've been able to successfully call the broadcast block inline twice in a row. (Although, I haven't tested it with “return” in variable form - I have only tested it with “return” in list form.)
When setting the variable arg1 to the return value and calling the broadcast a second time inline, the project always got stuck in an infinite loop (somehow? maybe I should look at how it's being interpreted…) no matter if I set the variable through a return value as a list or a variable.

In any case, I really need to get to bed, so I can't continue my experiments right now.
Interesting. When I tested, it ran, but it ran after running the rest of the block.
WOW! This can be really useful
scratchyone
Scratcher
100+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

_TigerJack21_ wrote:

scratchyone wrote:

This is really nice!

Self-Advertisment:
I just finished an editor that gets a scratch project from url, lets you edit the json, and then rezips it automatically.
https://scratchyone.github.io/sb2edit/

TheMonsterOfTheDeep wrote:

I've been trying to solve some of the issues with these “inline,” so to speak, functions/blocks/whatever with broadcasts.

Here are the results I have gotten so far:
When simply setting the arguments (variables arg1 and arg2) to constants, I've been able to successfully call the broadcast block inline twice in a row. (Although, I haven't tested it with “return” in variable form - I have only tested it with “return” in list form.)
When setting the variable arg1 to the return value and calling the broadcast a second time inline, the project always got stuck in an infinite loop (somehow? maybe I should look at how it's being interpreted…) no matter if I set the variable through a return value as a list or a variable.

In any case, I really need to get to bed, so I can't continue my experiments right now.
Interesting. When I tested, it ran, but it ran after running the rest of the block.
WOW! This can be really useful
Thanks
I made it because I hated hacked blocks because they were such a pain

Back on topic, though.
Jonathan50
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

Hardmath123 wrote:

TheLogFather wrote:

TheLogFather wrote:

Anyway, let's make it look even worse, and nest them:
say (letter {set [var1 v] to (join [a] (letter {set [var2 v] to (join [b] (letter {set [var3 v] to (join [c] (letter {set [var4 v] to [d]} of []))} of []))} of []))} of [])
Oh dear… I must've been getting rather tired when I wrote that, since I look at it now, with fresh eyes, and it's quite obviously going to execute in the wrong order – the “set var4” will evaluate first.

Ah well, it was just a bit of fun…

You also just re-invented monads, so that's something to be proud of.
What does that have to do with monads?
PullJosh
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

scratchyone wrote:

This is really nice!

Self-Advertisment:
I just finished an editor that gets a scratch project from url, lets you edit the json, and then rezips it automatically.
https://scratchyone.github.io/sb2edit/
Really cool!
scratchyone
Scratcher
100+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

Has anybody figured out a way to have ifs in custom reporters?

(And bump)
joefarebrother
Scratcher
500+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

Haven't we already discovered we can have ifs and if/elses with one block in? If so, we just need to nest another “custom reporter” in there.
TheLogFather
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

scratchyone wrote:

Has anybody figured out a way to have ifs in custom reporters?

(And bump)
Yes, as I mentioned, there can only be a single block within each branch of the “if” / “if … else”.

However, as joefarebrother mentions above, we already know how to run multiple blocks within a single block, so you should be able to stuff this:
if <some condition :: grey> then
set [ret v] to (join (letter (({set [v1 v] to [a]}+{set [v2 v] to [b]})+({set [v3 v] to [c]}+{set [v4 v] to [d]})) of []) (expr1 :: grey) )
else
set [ret v] to (join (letter (({set [v1 v] to [d]}+{set [v2 v] to [c]})+({set [v3 v] to [b]}+{set [v4 v] to [a]})) of []) (expr2 :: grey) )
end
…inside this:
( join (letter [PUT ABOVE IF+ELSE IN HERE] of []) (ret) )
…if you /really/ want to…

TheLogFather
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

It's because of this topic that I remembered I should've made this speed-test demo project a long time ago:


Nested expressions are bad for performance

Hopefully you can see the potential relevance to this discussion!

(Of course, such things are not going to be much of a concern for most projects…)

Last edited by TheLogFather (May 14, 2016 17:11:18)

bobbybee
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

TheLogFather wrote:

It's because of this topic that I remembered I should've made this speed-test demo project a long time ago:


Nested expressions are bad for performance

Hopefully you can see the potential relevance to this discussion!

(Of course, such things are not going to be much of a concern for most projects…)

It's a big deal for us compiler writers ^_^
joefarebrother
Scratcher
500+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

Do loops work? e.g. hacking the repeat block into a reporter slot
TheLogFather
Scratcher
1000+ posts

If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null?

joefarebrother wrote:

Do loops work? e.g. hacking the repeat block into a reporter slot
It can only do the first block.

The key thing is that the only place that Scratch can actually move on to the *next* block in a stack is in the *outer* execution loop: https://github.com/LLK/scratch-flash/blob/master/src/interpreter/Interpreter.as#L276-L292 (i.e. activeThread.block.nextBlock).

The only other thing it can do is “evalCmd” blocks that it comes across in two ways…

The first is nested blocks (which would normally refer to arguments of the currently executing block, so an expression containing, for example, operator blocks): https://github.com/LLK/scratch-flash/blob/master/src/interpreter/Interpreter.as#L351 and https://github.com/LLK/scratch-flash/blob/master/src/interpreter/Interpreter.as#L366

The second is when using startCmdList to start the first block of a substack, such as in a repeat loop, or in a branch of an “if” block: various primitives in https://github.com/LLK/scratch-flash/blob/master/src/interpreter/Interpreter.as#L444-455 and https://github.com/LLK/scratch-flash/blob/master/src/interpreter/Interpreter.as#L532 and https://github.com/LLK/scratch-flash/blob/master/src/interpreter/Interpreter.as#L554 etc.

In the case of a custom block, it also uses startCmdList to execute the first block: https://github.com/LLK/scratch-flash/blob/master/src/interpreter/Interpreter.as#L669 Unfortunately, that's only the define hat block in that case, which is a noop.

In none of those cases can it get back to that outer execution loop to find the just evaluated block's next block in the stack (i.e. block.nextBlock).

Last edited by TheLogFather (May 22, 2016 16:11:13)

  • Discussion Forums
  • » Advanced Topics
  • » If I stuff a `call` primitive where a reporter should go, will the procedure still be executed with side effects and simply return zero/null? [RSS Feed]

Powered by DjangoBB