Higher-order function works in REPL but not in batch execution

Hi guys,

I was amazed to discover Julia working also as a true functional language with true Higher-order functions.
Now, in writing small excerpts of Julia code to be included in a book sources, I found an inconsistency between compilation from REPL and execution from a batch file.

Any help? My example below has no dependencies, and is run on Julia-1.10-beta1, but same problem with julia-1.9. The executions follow. Thanks!

10:33 $ julia-1.10
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.10.0-beta1 (2023-07-25)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> B = n -> k -> u -> binomial(n,k) βˆ— u^k βˆ— (1-u)^(n-k)
#1 (generic function with 1 method)

julia> Bernstein(n) = map(B(n), collect(0:n))
Bernstein (generic function with 1 method)

julia> Bernstein(2)
3-element Vector{var"#3#6"{Int64, Int64}}:
 #3 (generic function with 1 method)
 #3 (generic function with 1 method)
 #3 (generic function with 1 method)

batch execution and error:

10:38 $ julia-1.10 /Users/paoluzzi/Documents/dev/PLASM/SPRINGER/BOOK/CODE/UnitTest/2.3.1.7-bernstein/bernstein-1.jl
β”Œ Error: JuliaSyntax parser failed β€” falling back to flisp!
β”‚   exception =
β”‚    Internal error: length(args) == 1
β”‚    Stacktrace:
β”‚      [1] error(::String, ::String)
β”‚        @ Base ./error.jl:44
β”‚      [2] internal_error(strs::String)
β”‚        @ Base.JuliaSyntax /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-4.0/build/default-macmini-x64-4-0/julialang/julia-release-1-dot-10/base/JuliaSyntax/src/utils.jl:23
β”‚      [3] _internal_node_to_Expr(source::Base.JuliaSyntax.SourceFile, srcrange::UnitRange{…}, head::Base.JuliaSyntax.SyntaxHead, childranges::Vector{…}, childheads::Vector{…}, args::Vector{…})
β”‚        @ Base.JuliaSyntax /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-4.0/build/default-macmini-x64-4-0/julialang/julia-release-1-dot-10/base/JuliaSyntax/src/expr.jl:191
β”‚      [4] _to_expr(node::Base.JuliaSyntax.SyntaxNode)
β”‚        @ Base.JuliaSyntax /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-4.0/build/default-macmini-x64-4-0/julialang/julia-release-1-dot-10/base/JuliaSyntax/src/expr.jl:496
β”‚      [5] _to_expr(node::Base.JuliaSyntax.SyntaxNode) (repeats 2 times)
β”‚        @ Base.JuliaSyntax /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-4.0/build/default-macmini-x64-4-0/julialang/julia-release-1-dot-10/base/JuliaSyntax/src/expr.jl:495
β”‚      [6] Expr(node::Base.JuliaSyntax.SyntaxNode)
β”‚        @ Base.JuliaSyntax /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-4.0/build/default-macmini-x64-4-0/julialang/julia-release-1-dot-10/base/JuliaSyntax/src/expr.jl:500
β”‚      [7] core_parser_hook(code::String, filename::String, lineno::Int64, offset::Int64, options::Symbol)
β”‚        @ Base.JuliaSyntax /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-4.0/build/default-macmini-x64-4-0/julialang/julia-release-1-dot-10/base/JuliaSyntax/src/hooks.jl:209
β”‚      [8] invoke_in_world(::UInt64, ::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
β”‚        @ Base ./essentials.jl:921
β”‚      [9] invoke_in_world(::UInt64, ::Any, ::Any, ::Vararg{Any})
β”‚        @ Base ./essentials.jl:918
β”‚     [10] (::Base.JuliaSyntax.var"#invoke_fixedworld#120"{…})(::String, ::Vararg{…}; kws::@Kwargs{})
β”‚        @ Base.JuliaSyntax /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-4.0/build/default-macmini-x64-4-0/julialang/julia-release-1-dot-10/base/JuliaSyntax/src/hooks.jl:118
β”‚     [11] (::Base.JuliaSyntax.var"#invoke_fixedworld#120"{…})(::String, ::Vararg{…})
β”‚        @ Base.JuliaSyntax /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-4.0/build/default-macmini-x64-4-0/julialang/julia-release-1-dot-10/base/JuliaSyntax/src/hooks.jl:117
β”‚     [12] _parse_string(text::String, filename::String, lineno::Int64, index::Int64, options::Symbol)
β”‚        @ Base.Meta ./meta.jl:200
β”‚     [13] #parseall#6
β”‚        @ Base.Meta ./meta.jl:294 [inlined]
β”‚     [14] parseall
β”‚        @ Base.Meta ./meta.jl:293 [inlined]
β”‚     [15] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
β”‚        @ Base ./loading.jl:2056
β”‚     [16] _include(mapexpr::Function, mod::Module, _path::String)
β”‚        @ Base ./loading.jl:2130
β”‚     [17] include(mod::Module, _path::String)
β”‚        @ Base ./Base.jl:489
β”‚     [18] exec_options(opts::Base.JLOptions)
β”‚        @ Base ./client.jl:318
β”‚     [19] _start()
β”‚        @ Base ./client.jl:552
β”‚    Some type information was truncated. Use `show(err)` to see complete types.
β”‚   offset = 0
β”‚   code = "julia> B = n -> k -> u -> binomial(n,k) βˆ— u^k βˆ— (1-u)^(n-k)\njulia> Bernstein(n) = map(B(n), collect(0:n))\nBernstein (generic function with 1 method)\njulia> Bernstein(2)\n3-element Vector{var\"#37#40\"{Int64, Int64}}:\n#37 (generic function with 1 method)\n#37 (generic function with 1 method)\n#37 (generic function with 1 method)"
β”” @ Base.JuliaSyntax /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-4.0/build/default-macmini-x64-4-0/julialang/julia-release-1-dot-10/base/JuliaSyntax/src/hooks.jl:258
ERROR: LoadError: syntax: "Bernstein(n)" is not a valid function argument name around /Users/<path-to-file>/bernstein-1.jl:2
Stacktrace:
 [1] top-level scope
   @ ~/<path-to-file>/bernstein-1.jl:2
in expression starting at /Users/<path-to-file>/bernstein-1.jl:2

It seems, you have the REPL prompt

julia>

pasted in your julia program file.

3 Likes

Thank you for fast answer! I removed julia> but got similar error :

**ERROR:** LoadError: syntax: "Bernstein(n)" is not a valid function argument name around /Users/<path-to-file>/UnitTest/2.3.1.7-bernstein/bernstein-1.jl:2

sorry, I didn’t removed anything (REPL answers included).
Removed all, It is OK

PS: But how to include a REPL log in a batch execution?
Is it possible?

I don’t know if there is some comfortable way to do this.

Running a .jl file just isn’t capable of the prompt pasting feature of the REPL. Prompt pasting is designed for copy-pasting within the REPL, and the julia> is needed to distinguish runnable lines and ignorable printouts. .jl source code should not have julia> or printouts to begin with, and it’s not worth making another file format just for prompt pasting.

So how do we isolate the commands? The prompt pasting parsing isn’t exposed as a function so we can’t repurpose that. But when we press the up arrow we do cycle through previous commands, so those are directly stored somewhere. But tracking down some internal file to copy from is very cumbersome, which is why someone made a package REPLHistory.jl for it:

julia> using REPLHistory

julia> a = rand(3);

julia> b = a .+ 1;

julia> print(history()) # default n=5, last 4 commands
using REPLHistory
a = rand(3);
b = a .+ 1;

julia> print(history(3)) # n-1 commands
b = a .+ 1;
print(history())

It’s not perfect. One strange thing is if you repeat a history call it seems to fail to include those calls until you change the argument. Otherwise it seems to do the job of making past REPL code easy for you to copy. Bear in mind it’s not an active project so it may not work by some later Julia version, but the source code is just 1 function so it’s much easier to patch.