Concrete Syntax Matching in Rascal - rascal

If I have:
import demo::lang::Exp::Concrete::WithLayout::Syntax;
if ((Exp)`<IntegerLiteral e> + <IntegerLiteral e>` := (Exp)`5 + 6`) {
println(e);
}
This prints 6. Is this a possible bug or a design decision, e.g. because of performance considerations? It should of course not print anything, since e cannot be matched to both 5 and 6. This is, however, in contrast to matching with ADTs, where this is caught, i.e.:
data ExpNum = numb(int n) | add(ExpNum e1, ExpNum e2);
if (add(numb(x), numb(x)) := add(numb(5), numb(6))) { println(x); }
Will not print a number, while it does print a number when using numb(5) instead of numb(6).
Ps. I ran the example both from Rascal source using Eclipse Plug-in Development (using a forked version merged with the latest version of Rascal), as well as on two machines using the official Eclipse plugin. The plugin, however, returned the following on both machines:
|stdin:///|(4,46,<1,4>,<1,50>): Java compilation failed due to with classpath [/home/wouter/eclipse//plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar]: package org.eclipse.imp.pdb.facts.type does not exist
The reason why I am asking is because, somewhat similarly, ConcreteListVariablePattern automatically throws a RedeclaredVariable-exception without checking if the match result's value is equivalent to the variable in the environment, in contrast to e.g. QualifiedNamePattern which checks if the result is equivalent to the value in the environment in case of a readily declared variable.
Thank you!

This is definitely a bug: the variable e is declared twice (without warning), the match succeeds and the binding to second e is printed.
Expected behavior would be that a RedeclaredVariable exception is thrown.
A work around is as follows:
if ((Exp)`<IntegerLiteral e1> + <IntegerLiteral e2>` := (Exp)`5 + 6` && e1 == e2) {
println(e1);
}

Related

Why does F# interactive console not consider "assert (2=3)" as wrong?

I send this line to F# interactive console in Visual Studio
assert (2=3)
To my surprise, the console does not report errors, but
 
val it : unit = ()
Similarly, if I run
printf ("hello!")
assert (2=3)
printf ("hello2")
on an REPL, I got "hellohello2" without any error messages.
How could I make the F# interactive tell me 2=3 is wrong?
Under the cover, the assert keyword translates to a method call to the Debug.Assert method from the .NET library (see the method documentaiton). This has a conditional compilation attribute [Conditional("DEBUG")], meaning that the call is only included if the symbol DEBUG is defined.
By default, this is not the case in F# Interactive. You can do that by adding --define:DEBUG to the command line parameters for fsi.exe. This will be somewhere in the options of your editor, depending on what you are using. For example, in Visual Studio, you need something like this:
EDIT: How to do something like this if you do not want to modify the command line parameters? This really depends on what exactly behaviour you want. The default behaviour of assert is that it shows a message box where you can either terminate the program or ignore the error. You could do that using:
open System.Windows.Forms
let ensure msg b =
let res =
MessageBox.Show("Assertion failed: " + msg +
"\n\nDo you want to terminate the exection? Press 'Yes' " +
"to stop or 'No' to ignore the error.", "Assertion failed",
MessageBoxButtons.YesNo)
if res = DialogResult.Yes then exit 42
ensure "Mathematics is broken" (2=3)

Am I using TextLoader wrong when running the ML.Net Iris demo in F#?

I am new to F#/.NET and I am trying to run the F# example provided in the accepted answer of How to translate the intro ML.Net demo to F#? with the ML.NET library, using F# on Visual Studio, using Microsoft.ML (0.2.0).
When building it I get the error error FS0039: The type 'TextLoader' is not defined.
To avoid this, I added the line
open Microsoft.ML.Data
to the source.
Then, however, the line
pipeline.Add(new TextLoader<IrisData>(dataPath,separator = ","))
triggers:
error FS0033: The non-generic type 'Microsoft.ML.Data.TextLoader' does not expect any type arguments, but here is given 1 type argument(s)
Changing to:
pipeline.Add(new TextLoader(dataPath,separator = ","))
yields:
error FS0495: The object constructor 'TextLoader' has no argument or settable return property 'separator'. The required signature is TextLoader(filePath: string) : TextLoader.
Changing to:
pipeline.Add(new TextLoader(dataPath))
makes the build successful, but the code fails when running with
ArgumentOutOfRangeException: Column #1 not found in the dataset (it only has 1 columns), I assume because the comma separator is not correctly picked up (incidentally, you can find and inspect the iris dataset at https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data).
Also
pipeline.Add(new TextLoader(dataPath).CreateFrom<IrisData>(separator: ','))
won't work.
I understand that there have been changes in TextLoader recently (see e.g. https://github.com/dotnet/machinelearning/issues/332), can somebody point me to what I am doing wrong?
F# just has a bit of a different syntax that can take some getting used to. It doesn't use the new keyword to instantiate a new class and to use named parameters it uses the = instead of : that you would in C#.
So for this line in C#:
pipeline.Add(new TextLoader(dataPath).CreateFrom<IrisData>(separator: ','))
It would be this in F#:
pipeline.Add(TextLoader(dataPath).CreateFrom<IrisData>(separator=','))

F# function changes type when compiled with standalone switch and referenced from another project

In a Visual Studio project for an F# library I have defined a function as
let inline Estimate (s : ^a seq) (f : float) (w : int) : float * float = ..
The type of Estimate is
val Estimate : s:seq<'a> -> f:float -> w:int -> float*float
Calling Estimate from a script within that project works as expected.
Now if I compile the project with the --standalone switch and reference the output DLL from another project, Estimate is shown to be
Estimate<'a,'a>(s: Collections.Generic.IEnumerabls<'a>, f: float, w:int) : float*float
i.e. it some reason now takes tuple arguments.
Thus the following does not work
let q, p = EstimationQuality.Estimate x f 1 // This value is not a function and cannot be applied
but calling it with tuple parameters works fine
let q, p = EstimationQuality.Estimate (x, f, 1) // No problem.
What's wrong here? Is it a bug in the compiler?
EDIT:
Digging a little deeper, it appears that the problem is linked with the use of LanguagePrimitives.GenericZero.
While the problem actually compiles with the tuple parameter call, i get a runtime error when Estimate is called.
An unhandled exception of type 'System.TypeInitializationException'
occurred in LibraryTest.dll
Additional information: The type initializer for
'GenericZeroDynamicImplTable`1' threw an exception.
Compiling an F# DLL which is intended to be used from F#, with the standalone switch is not a good idea.
Why? Because all the F# metadata is lost since the whole set of F# types are included in your DLL so those types get a different identity from the types of the F# application that call your DLL or fsi.
The caller assembly uses the types in Fsharp.Core.dll which now are not the same as the ones used in your standalone compiled DLL.
That's why you see the tupled arguments, as seen from C# which doesn't understand F# metadata at all.
Generic inline functions using static constraints break as well since they need the metadata to inline at the call site.
Compiling also the caller assembly as standalone would make things worse, then you will have 3 sets of Fsharp types with different identities.
I think the standalone switch is fine when used only in the 'end-user' application.

Compile with standalone flag gives compilation errors in client code

I'm attempting to compile Zero29 with the --standalone compiler flag. The project itself compiles fine, but I have a unit test project that exercises some code in the Zero29 project, even though it's an executable program (.exe).
Everything works fine without the --standalone compilation flag.
However, when I add the --standalone compilation flag to the Zero29 project, the Zero29 project compiles fine, but in the unit test project, the compiler complains about this Discriminated Union defined in the Zero29 project:
namespace Ploeh.ZeroToNine
open System
open Ploeh.ZeroToNine.Versioning
type Arg =
| Assign of Version
| AssignRank of Rank * int
| Increment of Rank
| ListVersions
| ShowHelp
| Unknown of string list
The unit test project directly references the Zero29 project:
Zero29.UnitTests --references--> Zero29 (where --standalone is added)
When I attempt to compile the entire solution, the Zero29 project compiles with the --standalone flag, but then compilation of Zero29.UnitTests fails. There are several errors, but they are all the same, so here's a single example:
error FS0039: The value or constructor 'Assign' is not defined
Which points to the third line of this code:
let ParseAssignVersionReturnsCorrectResult(version : string) =
let actual = [| "-a"; version |] |> Args.Parse
verify <# [Assign(Version version)] = (actual |> Seq.toList) #>
The strange thing is that while the compiler complains about Assign in the third line of this code snippet, it doesn't complain about the use of Args.Parse, even though it's defined in the same code file as the Arg Discriminated Union.
Why does it do that, and how can I resolve this issue?
(I've attempted to distil the problem here, but the links I've provided point to the actual code files on GitHub, if more information is required.)
Libraries compiled with the --standalone switch cannot expose any F# datatypes. This is, for one, expressly stated in Pickering (2007), p. 210. In your case, a discriminated union is one of these prohibited types. The fact that the file is an executable changes nothing here: it becomes a library the moment you attempt to use it as one.
There have been also multiple reports (for example, here and here) that even libraries compiled with --standalone behave, quoting one of these sources, “funky.” It would be safe to say that the use of this switch should perhaps be limited to stand-alone executables only (and they cannot pretend to be a library even when under unit tests).
Pickering R. (2007). Foundations of F#. Apress.

Orbeon 4.3 and localistion

I am trying to create an additional language entry for orbeon 4.3pe following this guide:
http://wiki.orbeon.com/forms/doc/contributor-guide/localizing-orbeon-forms
I did this couple of times for older versions of Orbeon (4.2 and 4.0) and it always worked that way.
The moment I remove the app/fr/i18n directory the application starts to work again.
When I start the application I get this error:
Toggle org.orbeon.saxon.trans.XPathException
Exception Class org.orbeon.saxon.trans.XPathException
Message An empty sequence is not allowed as the first argument of xxf:format-message()
The error seems to come from oxf:/apps/fr/components/components.xsl
The additional information:
element →
evaluating XPath expression
expression → xxf:format-message( $fr-resources/errors/form-title, ( xxf:instance('fr-error-summary-instance')/visible-counts/(if (count((#error, #warning, #info)[. gt 0]) gt 1) then 3 else if (#error gt 0) then 0 else if (#warning gt 0) then 1 else if (#info gt 0) then 2 else 4), xxf:instance('fr-error-summary-instance')/visible-counts/xs:integer(#alert), $title ) )
The most likely scenario is that you are providing a resources.xml file which does not match the one that ships with that specific Orbeon Forms version. Try this:
extract resources.xml from orbeon-form-runner-jar, or check this version on github for 4.3
in that file, compare the English section with your language section, and see if resources entries are not matching

Resources