dataquery1.nim(216) rows_from_disk SIGSEGV: Illegal storage access. (Attempt to read from nil?) Error: execution of an external program failed: '/Users/bobgus/dataquery/dataquery1 '
The program segment is:
proc rows_from_disk(acctnum: string, year: string): seq[Row] = let row_access = "row_data$1-$2.txt" for fname in walkFiles(row_access % [acctnum, year]): var line: string = "" let fin: File = open(fname, fmRead) while fin.readline(line): var row: Row = @[] var fields: seq[string] fields = line.split("\t") for field in fields: row.add(field) 216 result.add(row)
After beating up the readLine statement and adding all kinds of echo debugging statements, I finally looked closer at line 216. What could be wrong with this? The type of result is defined by the type given on the proc line. There is no 'reading' on line 216.
The solution was to add a line to initialize the 'result':
proc rows_from_disk(acctnum: string, year: string): seq[Row] = result = @[] let row_access = "row_data$1-$2.txt" ...
I wonder if it is reasonable for the compiler to initialize 'result structures' in general.
This might save some agony and perhaps simplify the compiler code - fewer diagnostic messages would be needed.
The 'type' of the result variable is known already. A default initialize could be added.
It the default initialize was incorrect for a particular usage, a custom initialize could be added by the compiler user, but this case would probably be far less frequent than the case where the default does the job.
AFAIK seq[T] can be nil and this is what result is initialized to. So making it initializing to something different (like the empty seq here) may arise a multitude of compatibility problems.
proc foo(): seq[Row] =
discard
echo foo() # nil
proc foo(): seq[Row] not nil =
discard # gives a warning "can't prove that it is initialized"
echo foo() # nil
proc foo(): seq[Row] not nil =
result = @[] # gives an error at compile time which is a compiler bug ATM :(
echo foo() # should be @[]
So making it initializing to something different (like the empty seq here) may arise a multitude of compatibility problems.
Since Nim is still a bit experimental, it might be interesting to change the default from Nil to something more appropriate to the 'type' of the result. That there is a pre-defined 'result' variable is quite progressive - compared to other languages. Appropriate initialization would finish the job.
I will skip over the issue of initializing 'result' for all proc types. (There are a finite number of basic types..)
Concentrating on the convenience variable 'result' for the case where the proc type is seq[T].
Is there anything useful about having 'result: seq[T]' initialized to Nil? I suppose it could be tested with the extraneous 'not nil' test, but what about in real code - once you have a seq[T] variable initialized to something, can you ever get it to be Nil? Deleting all of the items in the seq will give an empty seq. Why introduce problems by having the convenience variable 'result' initialized to Nil. It seems like just asking for trouble.
The little nonsense program below will give the appropriate runtime error message.
proc seqNilTest: seq[string] = result = @[] result.add("hello") echo(result.repr) delete(result,1) echo(result.repr) delete(result,1) echo(result.repr) echo(seqNilTest())
var s: seq[int] = @[]
s=nil
Some forum issues: quotations (by ">") stopped to work, and no margin around code-blocks.
once you have a seq[T] variable initialized to something, can you ever get it to be Nil?
Yes, your answer to my question certainly does the trick.
I will rephrase the question:
For a result variable in a proc with exit type 'seq[T]', why would you want a nil output?
I can see an empty output @[], but nil seems to be asking for trouble at the next step.
one may consider forbidding nil valua at all
That is a great idea!
I really like Nim. In its day, I really liked Pascal (took care of my mistyping of variable names). My previous liked language is Ruby (there is a wonderful ecosystem built up on Ruby - RubyOnRails, Homebrew, etc.).
I am hoping that Newbie's coming along after me - will also like Nim - and do great things with Nim.
Odd compiler messages don't help Newbies. I think proc with a pre-initialized convenience variable 'result' when seq[T] is the output would help those future Newbies. More experienced programmers may want to write their high performance routines in 'C'.
As others said: Empty sequences are a waste of time. Check "result" against nil in your loop. If nil, initialize with @[row] directly. If not nil, use the result.add function instead.
" More experienced programmers may want to write their high performance routines in 'C'."
It depends. Principally, you don't gain much with C. I miss direct embedding of a seq into an object. However, I can make a workaround using "unsafeNew" - getting a Seq for free.
Odd compiler messages don't help Newbies. > I think proc with a pre-initialized convenience variable 'result' when seq[T] is the output would help those future Newbies. > More experienced programmers may want to write their high performance routines in 'C'.
I don't think someone likes odd compiler messages. Nim messages are really not that bad, I generally see the reason for the messages immediately. The exception is macros, but I still have to learn much about macros... Have you ever used BOOST or CGAL C++ library with all its templates? I was really unable to understand the gcc messages...
Generally my feeling is that Nim is not a language with main target audience "Newbies". Of course it is an easy language when compared to C++, Rust or Haskell, and syntax similarity to Python may attract people without much knowledge. But my impression is that most Nim users are very smart, and that even most beginners try to become smart. And no, Nim users do not want to write their high performance routines in 'C'. For Ruby or Python we have to do it -- I came to Nim to avoid exactly that.
I was really unable to understand the gcc messages...
GCC has a basic problem. It converts source code to an intermediate language. When a subsequent problem is detected by the compiler, there isn't a lot of original source code to tie error messages to. Clang is much better in this regard.
Generally my feeling is that Nim is not a language with main target audience "Newbies".
All languages start out with a flock of Newbies. It is unavoidable.
Stefan_Salewski: "Generally my feeling is that Nim is not a language with main target audience "Newbies". Of course it is an easy language when compared to C++, Rust or Haskell, and syntax similarity to Python may attract people without much knowledge. But my impression is that most Nim users are very smart, and that even most beginners try to become smart. And no, Nim users do not want to write their high performance routines in 'C'. For Ruby or Python we have to do it -- I came to Nim to avoid exactly that."
I think Nim is easy to learn, especially for newbies. We have a nice python-style-syntax with the speed of C.
However, things become way more complicated, when it comes to the ecosystem of Nim or templates or macros.
I don't see Nims target audience so much in programming newbies. You can use it to introduce some basic programming concepts but Nim generally has ideas and concepts which are far beyond what I would consider "newbie territory".
Saying "everybody is once a newbie to Nim" is right, but I don't think you can say that the compiler errors are much of a barrier. At least not after you get some of the terminology into your head (like: is discarded).
I can't speak for others but I am interested in Nim because I believe it offers me more than other languages in a nice package. This is definitely not because it is "newbie friendly".
There a for sure people coming from Python and think: Hey this seems to be familiar. At first... But Nim is no "magically C speed Python". It is "Nim" and has it own positive and negative aspects.
For me the question is: What can we do to make Nim a better tool for the experienced programmer? The one who is searching for a language as "better tool" than other tools he already uses. To give him power for his job or hobby programming tasks.
I do not really think that it is about the "programming newbies" experience. Nim as language is pushed by it's potent and advanced features. That you can write simple programs quick is just an extra. One which makes it replacing more other tools in a toolbox. Giving synergies you don't have using a mixture of "Python + C + Javascript" for the same task.
I love this! I don't like the mixing of result and return in the same function, and although I lost that argument (my proposal to ban their mixing), at least Nim will force users to initialize a complex result if they plan to use the implicit return.
I would echo the sentiments of @OderWat.
@LeuGim, the forum is written in Nim and hosted in GitHub. @Dom96 maintains that, and if you find a bug, I'm sure he'd appreciate a pull-request.
In the new nim 19.0, nil and seq of length 0 are the same. So you should not run into this as often.
These are now all valid and work:
var a: seq[int]
a.add 1
var b = newSeq[int]()
b.add 1
var c: seq[int] = @[]
c.add 1
initializing all seq[] with a dummy variable then wiping them before their intended use - this seems really strange, but if it works for you it works.