Problems with Code in the Frege REPL - frege

While trying to learn Frege I copied some code from Dierk's Real World Frege to the online REPL an tried to execute it (see also How to execute a compiled code snipped in Frege online repl). The scripts I've tried don't compile :-(
What am I doing wrong?
Here are examples of what does not compile:
println ( 2 *-3 ) -- unlike haskell, this will work!
and the whole ValuesAndVariables.fr code

It is unavoidable that over the course of more than a year, an evolving language (and its libraries) change so that older code will not compile anymore.
It would be nice, if we could see an example, instead of a generalization like "most".
The next best thing would be to have an issue in Dierks project that points to the error(s).
But the very best would be en effort to find out what is wrong. This would also intensify your learning process.
Here are two ressources that could help:
https://github.com/Frege/frege/wiki/New-or-Changed-Features -- the release notes for every release, contains a summary of things that have changed between releases, and especially the reasons why code would not compile anymore and how to correct it.
http://www.frege-lang.org/doc/fregedoc.html -- the library docs. May explain possible errors like import not found, or missing identifiers.
Go, give it a try. And I'm convinced Dierk will be happy to accept pull requests.
Edit: Fixes for announced errors.
The error in:
println ( 2 *-3 )
stems indeed from a syntactical change.
It is, as of recently, demanded that adjacent operators be separated by at least one space.
Hence
println (2 * -3)
However, the error message you got here was:
can't resolve `*-`, did you mean `-` perhaps?
which could have triggered the idea that it tries to interpret *- as a single operator.
The other error in ValuesAndVariables1.fr is indeed a show stopper for a beginner. The background is that we have one pi that has type Double and one that has type Float and potentially many more through type class Floating, so one needs to tell which one to print.
The following will work:
import Prelude.Math -- unless already imported
println Float.pi
println (pi :: Double)

the online REPL at http://try.frege-lang.org is currently based on Frege V3.23.370-g898bc8c . Dierk's code examples are based on V3.21.500-g88270a0 (which can be seen in the gradle build file).
It seems that the Frege developers decided to change the Frege syntax slightly between those versions. THe result is that you will not be able to run these code snippets in the online REPL anymore.

Related

How do you get Haskell to check SQL at compile time?

I know it can be done, but I'm having trouble getting it working. I'm still finding my feet with Haskell.
I tried using postgresql-typed, but it wouldn't compile. They don't enable the QuasiQuotes extension, so I don't understand how their code would ever compile. It also fails with an error on the useTPGDatabase statement. I cloned the library's source code from Github, but their tests failed to compile using stack with exactly the same errors.
I considered using hasql-th, but it's not on stackage.org, which immediately puts it in the "too hard basket.". I considered switching to nix but that seems like even more effort.
Does somebody have a reliable recipe for getting an environment working that type-checks SQL at compile time in Haskell?
I considered using hasql-th, but it's not on stackage.org, which immediately puts it in the "too hard basket."
All you need to do is add the latest version of hasql-th to the extra-deps section of your stack.yaml file and all other deps that Stack will suggest to you when you build.
In the end your stack.yaml file should look something like this:
resolver: lts-17.9
extra-deps:
- hasql-th-0.4.0.8
- headed-megaparsec-0.1.0.4
- postgresql-syntax-0.3.0.3
Anticipating a question in the spirit of "Why is it not listed on Stackage?" It's just that nobody has gotten to list these packages yet.

Useless use of LOOP_BLOCK_1 symbol in sink context

With a snippet like
perl6 -e 'loop { FIRST say "foo"; last }'
I get
WARNINGS for -e:
Useless use of LOOP_BLOCK_1 symbol in sink context (line 1)
foo
I know how to work around the warning. I'm wondering about what the source of the warning is. I found this open ticket, but it doesn't seem to have received any attention.
What is this warning about?
And what about this is useless?
Version
$ perl6 --version
This is Rakudo version 2018.06 built on MoarVM version 2018.06
implementing Perl 6.c.
It's a bug, a bogus warning.
I know how to work around the warning.
That's the main thing.
I'm wondering about what the source of the warning is.
It's a bogus warning from the compiler.
I found this open ticket, but it doesn't seem to have received any attention.
I think it got some attention.
bbkr, who filed the bug, linked to another bug in which they showed their workaround. (It's not adding do but rather removing the FIRST phaser and putting the associated statement outside of the loop just before it.)
If you follow the other links in bbkr's original bug you'll arrive at another bug explaining that the general "unwanted" mechanism needs to be cleaned up. I imagine available round tuits are focused on bigger fish such as this overall mechanism.
Hopefully you can see that it's just a bizarre warning message and a minor nuisance in the bigger scheme of things. It appears to come up if you use the FIRST phaser in a loop construct. It's got the very obvious work around which you presumably know and bbkr showed.
What is this warning about?
Many languages allow you to mix procedural and functional paradigms. Procedural code is run for its side effects. Functional code for its result. Some constructs can do both.
But what if you use a construct that's normally used with the intent of its result being used, and the compiler knows that, but it also knows it's been used in a context in which its value will be ignored?
Perls call this "useless use of ... in sink context" and generally warn the coder about it. ("sink" is an alternative/traditional term for what is often called "void" context in other language cultures.)
This error message is one of these warnings, albeit a bogus one.
And what about this is useless?
Nothing.
The related compiler warning mechanism has gotten confused.
The "Useless use of ... in sink context" part of the message is generic and hopefully self-explanatory.
But there's no way it should be saying things like "LOOP_BLOCK_1 symbol". That's internal mumbo-jumbo.
It's a warning message bug.

Change REPL module/namespace in Julia

I'm looking for a way to "enter" a module in the REPL, so that I can access all symbols without qualification (not just the exported ones), and any function (re)defined at the REPL gets in the specified module. (Basically this is the functionality of Common Lisp's in-package macro.)
This would be useful in a REPL-oriented workflow, as I would be able to write the same code in the REPL as in the module I am developing.
The manual recommends a workflow where I qualify everything, but that seems annoying.
I started a package called REPLMods.jl for this a while back. It should probably be polished up, but I haven't had the time.
I spoke to core Julia members and there was interest in getting it merged into base once things were clean, but again, no time!
I know this isn't quite what you're asking, but just in case the 'obvious' had not occured to you (or future visitors to the question), assuming you loaded a module with an annoyingly cumbersome name, e.g.
import LaTeXStrings
and you don't want to have to type LaTeXStrings all the time just to explore its accessibles, i.e.
LaTeXStrings.[TAB]
you can just assign the imported module as a whole to another variable, i.e.
const l = LaTeXStrings
I'm sure in the absence of a more appropriate built-in solution, at least typing l.[TAB] as opposed to LaTeXStrings.[TAB]is a lot more tolerable :)
(I find it odd, in fact, that julia doesn't seem to support the import LaTeXStrings as l syntax ...)
It's 2020, I'm using Julia 1.4, and was unable to get REPLMods.jl to work. I think the following seem good enough for the time being:
ExportAll.jl - see Exporting all symbols in Julia for a discussion (just that one shouldn't ExportAll to replace normal export)
and Revise.jl

Elixir: lint for confirming that every function has type sepcification

Is there a lint for Elixir (like for Javascript) which checks that every function has a type specification?
There is an Erlang compiler switch, +warn_missing_spec, which does this, but I'm having trouble getting it to work with Elixir at the moment, I think there is a bug with it's parsing of the ELIXIR_ERL_OPTS environment variable which is converting +warn_missing_spec into -warn_missing_spec which isn't a valid compiler option. I'm going to open an issue on the tracker, but thought you might like to know that this does indeed exist.
EDIT: As José mentioned below, the correct flag is ERL_COMPILER_OPTIONS. You can enable the missing spec warning during compilation by doing the following:
ERL_COMPILER_OPTIONS="warn_missing_spec" mix compile
Keep in mind you may get superfluous warnings from Elixir itself, for functions like __MODULE__. It should still be useful though. One last thing to note, I discovered this morning that there is a problem using this flag with mix compile, and that it's currently only warning about mix.exs. This is being fixed, and may even be fixed by the time you see this, but it's something to be aware of.

How would one go about testing an interpreter or a compiler?

I've been experimenting with creating an interpreter for Brainfuck, and while quite simple to make and get up and running, part of me wants to be able to run tests against it. I can't seem to fathom how many tests one might have to write to test all the possible instruction combinations to ensure that the implementation is proper.
Obviously, with Brainfuck, the instruction set is small, but I can't help but think that as more instructions are added, your test code would grow exponentially. More so than your typical tests at any rate.
Now, I'm about as newbie as you can get in terms of writing compilers and interpreters, so my assumptions could very well be way off base.
Basically, where do you even begin with testing on something like this?
Testing a compiler is a little different from testing some other kinds of apps, because it's OK for the compiler to produce different assembly-code versions of a program as long as they all do the right thing. However, if you're just testing an interpreter, it's pretty much the same as any other text-based application. Here is a Unix-centric view:
You will want to build up a regression test suite. Each test should have
Source code you will interpret, say test001.bf
Standard input to the program you will interpret, say test001.0
What you expect the interpreter to produce on standard output, say test001.1
What you expect the interpreter to produce on standard error, say test001.2 (you care about standard error because you want to test your interpreter's error messages)
You will need a "run test" script that does something like the following
function fail {
echo "Unexpected differences on $1:"
diff $2 $3
exit 1
}
for testname
do
tmp1=$(tempfile)
tmp2=$(tempfile)
brainfuck $testname.bf < $testname.0 > $tmp1 2> $tmp2
[ cmp -s $testname.1 $tmp1 ] || fail "stdout" $testname.1 $tmp1
[ cmp -s $testname.2 $tmp2 ] || fail "stderr" $testname.2 $tmp2
done
You will find it helpful to have a "create test" script that does something like
brainfuck $testname.bf < $testname.0 > $testname.1 2> $testname.2
You run this only when you're totally confident that the interpreter works for that case.
You keep your test suite under source control.
It's convenient to embellish your test script so you can leave out files that are expected to be empty.
Any time anything changes, you re-run all the tests. You probably also re-run them all nightly via a cron job.
Finally, you want to add enough tests to get good test coverage of your compiler's source code. The quality of coverage tools varies widely, but GNU Gcov is an adequate coverage tool.
Good luck with your interpreter! If you want to see a lovingly crafted but not very well documented testing infrastructure, go look at the test2 directory for the Quick C-- compiler.
I don't think there's anything 'special' about testing a compiler; in a sense it's almost easier than testing some programs, since a compiler has such a basic high-level summary - you hand in source, it gives you back (possibly) compiled code and (possibly) a set of diagnostic messages.
Like any complex software entity, there will be many code paths, but since it's all very data-oriented (text in, text and bytes out) it's straightforward to author tests.
I’ve written an article on compiler testing, the original conclusion of which (slightly toned down for publication) was: It’s morally wrong to reinvent the wheel. Unless you already know all about the preexisting solutions and have a very good reason for ignoring them, you should start by looking at the tools that already exist. The easiest place to start is Gnu C Torture, but bear in mind that it’s based on Deja Gnu, which has, shall we say, issues. (It took me six attempts even to get the maintainer to allow a critical bug report about the Hello World example onto the mailing list.)
I’ll immodestly suggest that you look at the following as a starting place for tools to investigate:
Software: Practice and Experience April 2007. (Payware, not available to the general public---free preprint at http://pobox.com/~flash/Practical_Testing_of_C99.pdf.
http://en.wikipedia.org/wiki/Compiler_correctness#Testing (Largely written by me.)
Compiler testing bibliography (Please let me know of any updates I’ve missed.)
In the case of brainfuck, I think testing it should be done with brainfuck scripts. I would test the following, though:
1: Are all the cells initialized to 0
2: What happens when you decrement the data pointer when it's currently pointing to the first cell? Does it wrap? Does it point to invalid memory?
3: What happens when you increment the data pointer when it's pointing at the last cell? Does it wrap? Does it point to invalid memory
4: Does output function correctly
5: Does input function correctly
6: Does the [ ] stuff work correctly
7: What happens when you increment a byte more than 255 times, does it wrap to 0 properly, or is it incorrectly treated as an integer or other value.
More tests are possible too, but this is probably where i'd start. I wrote a BF compiler a few years ago, and that had a few extra tests. Particularly I tested the [ ] stuff heavily, by having a lot of code inside the block, since an early version of my code generator had issues there (on x86 using a jxx I had issues when the block produced more than 128 bytes or so of code, resulting in invalid x86 asm).
You can test with some already written apps.
The secret is to:
Separate the concerns
Observe the law of Demeter
Inject your dependencies
Well, software that is hard to test is a sign that the developer wrote it like it's 1985. Sorry to say that, but utilizing the three principles I presented here, even line numbered BASIC would be unit testable (it IS possible to inject dependencies into BASIC, because you can do "goto variable".