# Why does Julia think a vector is a string?

This works perfectly, as expected:

julia> push!(S,[2,3,4])
Stack{Any}(Deque [Any[[2, 3, 4]]])

julia> push!(S,[5,6,7])
Stack{Any}(Deque [Any[[2, 3, 4], [5, 6, 7]]])

julia> x = pop()
3-element Vector{Int64}:
5
6
7

julia> y = pop()
3-element Vector{Int64}:
2
3
4

julia> +(x,y)
3-element Vector{Int64}:
7
9
11

But, when my program does the same thing:

julia> jacli()
S: [2,3,4]
execute: term = [2,3,4]

S[[2,3,4]]: [4,5,6]
execute: term = [4,5,6]

S[[2,3,4] [4,5,6]]: +
execute: term = +

apply: x = [4,5,6] y = [2,3,4]
ERROR: MethodError: no method matching +(::String, ::String)

The printout â€śapply: x = [4,5,6] y = [2,3,4]â€ť is one line before the expression f(x,y) where f = +, clearly showing that x and y are vectors. Why would Julia interpret them as strings?

What is this code? Where does `S` come from? What are you popping from here

?

Where does `jacli` come from?

What program?

This question is really confusing. Can you provide some context?

1 Like

The program is jacli. S = StackAny. jacli pushes literals, like vectors, onto S and executes functions, like +, by popping the appropriate number of stack terms, then applying the function to those terms. The operation f(x,y) where f = + and x and y are vectors, fails because Julia thinks x and y are strings! But the line â€śapply: x = [4,5,6] y = [2,3,4]â€ť printed at runtime, clearly shows they are not strings.

The jacli prompt shows the current stack then waits for input.

Sorry for the confusion.

You have a bug in your program but without reproducing enough of it here for us to try it out, it is impossible to say what it is.

2 Likes

The bug appears to be that Julia is treating vectors x and y as strings in the
expression +(x,y).

Should I post the source code to my program, itâ€™s rather long?

Quoting from Please read: make it easier to help you. You donâ€™t have to post whole source codes. Itâ€™s best to give us a self-contained minimal working example so we can reproduce your error. I believe people reading your post doesnâ€™t understand several things:

1. the process of defining S
2. what function is pop() (because it accepts no argument) in julia we have the method pop!()
3. what function is jacli()

and itâ€™s best to write your code in the triple-backticks. lastly, doing an addition of `Vector{Int64}` to another `Vector{Int64}` still results a `Vector{Int64}` the last time I checked.

``````
julia> x = [1,2,3]
3-element Vector{Int64}:
1
2
3

julia> y = [4,5,6]
3-element Vector{Int64}:
4
5
6

julia> +(x,y)
3-element Vector{Int64}:
5
7
9
``````

Edit: I see youâ€™ve edited the post @dgpdx to give an explanation, but still I havenâ€™t yet understand what happened

1 Like

What happened: my program tried f(x,y) where f = + and x an y are vectors. The program failed with the error msg: ERROR: MethodError: no method matching +(::String, ::String)
The problem is that x and y were vectors not strings.

S is defined as a Julia stack of any type.

pop() uses pop!(S), but first it ensures S is not empty, printing an error msg if it is.

jacli() is the name of the running program. The line **Julia jacli() should make that clear.

Here is a snippet of jacli output that shows + works fine for numeric literals, only failing for vector literals. jacl handles all literals identically.

## julia> jacli() jacl version 0.1

S: 4 5.0 +
S[9.0]: exit
ans = 9.0

I donâ€™t know how to respond to this. Surely you must understand that the name of a program you have apparently written yourself tells us nothing?

Can you copy paste from inside your function the code that defines `x` and `y` and what happens to it before the error occurs?

2 Likes

instead of describing it in everyday language, would you mind copy pasting your code that defines jacli()

in your IDE (or any place you write) it should be something like this:

``````function jacli(arguments)
# the function jacli
end
``````

and also the `pop()` function youâ€™re talking about

``````function pop()
# the function pop
end
``````

Not only is this incredibly helpful for anyone who wants to help you. In my experience the process of extracting a minimum example frequently uncovers absolutely embarrassing bugs or thought errors which Iâ€™m thankful that I donâ€™t have to show the world.

9 Likes
``````# Stack Operations
# ================
S = Stack{Any}()	# define the stack vector
P = Queue{Any}()	# define the program queue

function pop()
if length(S) > 0
pop!(S)
else
printstyled("\npop: stack underflow\n", color = :red)
end
end

function push(x)
push!(S,x)
end

# jacl interactive mode
# ---------------------
function jacli()
print("\njacl version \$version\n----------------")
empty!(S)
a = true
while a
prompt()
a = execute()
end
end

# execute program P
# -----------------
function execute()
for i = 1:length(P)				# process P
term = dequeue!(P)
if  isa(term,Number) ||		# is it a literal?
isa(term,Bool)
push!(S,term)			# yes
continue
elseif isa(term,Function)||	# is it a function?
term == dup  ||
term == drop ||
term == swap ||
term == rot  ||
term == under
apply(term)				# yes
continue
elseif term == "exit"		# is it exit?
ans = pop()				# quit
println("\nans = \$ans\n")
return false
else 						# must be a quotation
push!(S,term)
end
end
return true
end

# Apply the function f to the stack
# (S)f = S'
# ---------------------------------
function apply(f)
ar = methods(f).ms[1].nargs-1		# get function arity
if ar == 0
if f == dup   dup() end
if f == drop  drop() end
if f == swap  swap() end
if f == rot   rot() end
if f == under under() end
end
if ar == 1
x = pop()
push(f(x))
return
elseif ar == 2
x = pop()
y = pop()
push(f(x,y))
return
elseif ar == 3
x = pop()
x = pop()
z = pop()
push(f(x,y,z))
end
end
``````

The code is a bit difficult to follow, using global variables like this is not recommended. The important parts probably happen inside `makeP`, which I donâ€™t think you posted.

But I see you are using `readline` to create some data structure, so my guess is that `x` and `y` are strings from the very beginning. We need to see exactly how they are created, but this:

is clearly wrong, if you print the string `"[4,5,6]"` it will look like this.

4 Likes

Could you also place the code within three backticks, like this? It will also appear neatly indented.
`````
`code here`
`````.

I think youâ€™ve solved it. I was confused by thinking printing a string would show the quotes around it. Many thanks!

That still leaves me with a question I asked previously: how can I get [1,2,3] from â€ś[1,2,3]â€ť?
It seems I can print [1,2,3], but how can I assign it to a variable?

Conversely, is there a way to read a line of input from the console other than as a string?

Iâ€™ll remember this for next time, thanks.

Maybe `parse.(Int, split(strip(str, ['[', ']']), ','))`?

1 Like

No problem. Could you please edit your previous posts and apply the triple backticks? Other people may find this thread useful.

Thanks for the suggestion, but I donâ€™t want to strip the brackets, I want to strip the quotes. Iâ€™ve tried stripping the quotes, but it doesnâ€™t work.

Done!

1 Like

The output is a vector:

``````julia> parse.(Int, split(strip("[1,2,3]", ['[', ']']), ','))
3-element Vector{Int64}:
1
2
3
``````