a question about const(..)

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
User avatar
WhiteHare
Posts: 129
Joined: Thu Oct 04, 2018 4:00 am

a question about const(..)

Post by WhiteHare » Fri Oct 19, 2018 7:53 pm

Consider the simplified case of:

Code: Select all

x = const(0)
y = const(1000)
z = 0

while (const(x+y) > z):
    z = z + 1
Can I be confident that the expression (x+y) in const(x+y) is evaluated only once at compile time? i.e. 1000 would be substituted for the expression const(x+y)? Or will the same addition of (x+y) occur over and over again 1000 times?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: a question about const(..)

Post by dhylands » Sat Oct 20, 2018 12:47 am

If you run the unix version of micropython with two -v's on the command line then it will dump the bytecode. I modified your program to make it a bit clearer:

Code: Select all

x = const(100)
y = const(1000)
z = 0

while (const(x+y) > z):
    z = z + 1

Code: Select all

585 >./micropython -v -v c.py
File c.py, code block '<module>' (descriptor: 7f151b05df40, bytecode @7f151b05e2c0 65 bytes)
Raw bytecode (code_info_size=11, bytecode_size=54):
 02 00 00 00 00 00 0b 56 00 b6 02 27 26 44 23 00
 00 ff 14 80 64 24 b7 02 14 87 68 24 b8 02 80 24
 b9 02 35 09 80 1b b9 02 00 81 f1 24 b9 02 1b 09
 01 00 14 88 4c 64 01 1b b9 02 00 d8 36 e6 7f 11
 5b
arg names:
(N_STATE 2)
(N_EXC_STACK 0)
  bc=-1 line=1
  bc=6 line=2
  bc=12 line=3
  bc=16 line=5
  bc=19 line=6
00 LOAD_CONST_SMALL_INT 100
03 STORE_NAME x
06 LOAD_CONST_SMALL_INT 1000
09 STORE_NAME y
12 LOAD_CONST_SMALL_INT 0
13 STORE_NAME z
16 JUMP 28
19 LOAD_NAME z (cache=0)
23 LOAD_CONST_SMALL_INT 1
24 BINARY_OP 26 __add__
25 STORE_NAME z
28 LOAD_NAME const (cache=0)
32 LOAD_CONST_SMALL_INT 1100
35 CALL_FUNCTION n=1 nkw=0
37 LOAD_NAME z (cache=0)
41 BINARY_OP 1 __gt__
42 POP_JUMP_IF_TRUE 19
45 LOAD_CONST_NONE
46 RETURN_VALUE
Traceback (most recent call last):
  File "c.py", line 6, in <module>
NameError: name 'const' isn't defined
mem: total=3260, current=888, peak=2468
stack: 288 out of 80000
GC: total: 2072832, used: 960, free: 2071872
 No. of 1-blocks: 10, 2-blocks: 2, max blk sz: 6, max free sz: 64743
and we can see that at offset 32, it's comparing z to 1100.

I see an error (after I wrote this) that it doesn't like const, so I need to figure out how to enable that for the unix build.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: a question about const(..)

Post by dhylands » Sat Oct 20, 2018 12:53 am

It seems you can't use const in the while loop. I had to rewrite like this:

Code: Select all

x = const(100)
y = const(1000)
z = 0

c = const(x+y)

while (c > z):
    z = z + 1
and got this bytecode:

Code: Select all

598 >./micropython -v -v c.py
File c.py, code block '<module>' (descriptor: 7f3eb946ef40, bytecode @7f3eb946f2c0 66 bytes)
Raw bytecode (code_info_size=12, bytecode_size=54):
 02 00 00 00 00 00 0c 56 00 b6 02 27 26 44 46 23
 00 00 ff 14 80 64 24 b7 02 14 87 68 24 b8 02 80
 24 b9 02 14 88 4c 24 ba 02 35 09 80 1b b9 02 00
 81 f1 24 b9 02 14 88 4c 1b b9 02 00 d8 36 ec 7f
 11 5b
arg names:
(N_STATE 2)
(N_EXC_STACK 0)
  bc=-1 line=1
  bc=6 line=2
  bc=12 line=3
  bc=16 line=5
  bc=22 line=7
  bc=25 line=8
00 LOAD_CONST_SMALL_INT 100
03 STORE_NAME x
06 LOAD_CONST_SMALL_INT 1000
09 STORE_NAME y
12 LOAD_CONST_SMALL_INT 0
13 STORE_NAME z
16 LOAD_CONST_SMALL_INT 1100
19 STORE_NAME c
22 JUMP 34
25 LOAD_NAME z (cache=0)
29 LOAD_CONST_SMALL_INT 1
30 BINARY_OP 26 __add__
31 STORE_NAME z
34 LOAD_CONST_SMALL_INT 1100
37 LOAD_NAME z (cache=0)
41 BINARY_OP 1 __gt__
42 POP_JUMP_IF_TRUE 25
45 LOAD_CONST_NONE
46 RETURN_VALUE
mem: total=3206, current=722, peak=2564
stack: 288 out of 80000
GC: total: 2072832, used: 768, free: 2072064
 No. of 1-blocks: 6, 2-blocks: 1, max blk sz: 6, max free sz: 64743

pfalcon
Posts: 1155
Joined: Fri Feb 28, 2014 2:05 pm

Re: a question about const(..)

Post by pfalcon » Sat Oct 20, 2018 6:32 am

It seems you can't use const in the while loop.
Of course not. The only use for const is *defining* symbolic constants, before const there should be "=", and before it - the name of constant. Also, should be imported properly:

Code: Select all

from micropython import const
c = const(x+y)
This isn't needed, the sum of constants is a constant:

Code: Select all

x = const(100)
y = const(1000)
z = 0

while (x + y > z):
    z = z + 1

(For completeness, should be noted that constant propagation may be disabled by compile-time options, but any MicroPython port with enough codespace would have it enabled.)
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: a question about const(..)

Post by pythoncoder » Sat Oct 20, 2018 6:51 am

Looking at the bytecode on the Unix build

Code: Select all

c = const(x+y)
produces the expected

Code: Select all

50 LOAD_CONST_SMALL_INT 1100
53 LOAD_NAME z (cache=0)
57 BINARY_OP 1 __gt__
58 POP_JUMP_IF_TRUE 41
whereas

Code: Select all

c = x + y
produces a name lookup:

Code: Select all

50 LOAD_NAME c (cache=0)
54 LOAD_NAME z (cache=0)
58 BINARY_OP 1 __gt__
59 POP_JUMP_IF_TRUE 41
Peter Hinch
Index to my micropython libraries.

User avatar
WhiteHare
Posts: 129
Joined: Thu Oct 04, 2018 4:00 am

Re: a question about const(..)

Post by WhiteHare » Sun Oct 21, 2018 1:07 pm

Thanks everyone for the thoughtful responses. It was key to the writing of some demo code that I just now posted: viewtopic.php?f=12&t=5420

Post Reply