Does Scala have an equivalent to Haskell's Prelude.show? - java

Specifically I'm looking for a function that given a value will return a string that can be interpreted or compiled and give me back the same value.

For the built in types the toString() function does something similar. But you cannot use its result unmodified, e.g. it will skip the quotes in most strings (with exception to the empty string).
You could also try Scalaz shows which is similar to the Haskell show function and has similar type classes. But Scalaz is an extension library, so don't expect the same prevalence of these type classes as in Haskell.

Related

Explicit data types in Antlr4

i am new to Antlr and writing in java, and i am currently trying to figure out how i can make the parser identify the token "var" as either an int, string etc. Just as in javascript where you use either var or let. I am trying to make my own programming language which has explicit data types, so that it would be easier for a beginner to start coding, without worrying wether he/she is using an int/string/char and so on.
I dont seem to find any documentation for it online, so i am hoping that someone here can teach me in how i would make this possible
This isn't really a task you'd accomplish directly with ANTLR.
ANTLR generates code to produce a Parser for you. That means it will process your input and produce a data structure (a ParseTree in ANTLRs case), that correctly catagorizes all of your input (assuming it's syntactically correct; an error message otherwise).
In your case you'd have a ParseTree that would correctly identify that you have a var keyword, an Identifier (your variable name) an = and a value. This would probably be the result of matching matching a parse rule for something like assignmentStmt.
With that ParseTree in memory, you'll have listener and/or visitor classes that ANTLR generates to make it quite easy to navigate that ParseTree.
With everything parsed out for you (by ANTLR), it would be up to you, in your own code to do the type inference (what you are describing is type inference rather than "explicit typing"). Or, if you're wanting to allow any type to be assigned to your variable, you really don't have any thing you need to do (You have a typeless language, and no need to verify types. Your runtime would, of course, want to keep track of what the type of the currently assigned value is, but would allow assignment of a new value of any type.)
Antlr's job is to correctly identify all the parts according to your Syntax (Type checking is a Semantic concern, and not something the Parser concerns itself with). It does not create Symbol Tables for you, or attempt to do type inference. These are tasks that are up to you once the input is parsed.
Side note, JavaScript is untyped so, you just have a variable or constant, that can hold anything, there is no type (inferred, or explicit).
Explcit typing would be something like:
var myString : String;
Implcit typing would be something like:
var myVar = "String"
and you would have code that essentially says "They have assigned a String to myVar so, henceforth, myVar is a String type and will accept no value other than a String.
In JavaScript, you're just getting a variable, and you can turn right around as assign it a numeric value, an object, or anything you like (it's typeless).
A parser is a tool to determine if certain input is syntactically correct and can convert the input to a specific data structure, if that's the case (as Mike Cargal explained). That means a parser is a tool to deal with the syntax of the input.
Specifying types and other meta information of the input is applying meaning to certain strings, which is commonly called semantic processing.
Knowing that a parser is a syntax tool should make clear that a parser cannot be used to apply semantics. It's important to differentiate between syntax and semantic, to understand which tool can do what.
How to apply semantics in the way you seem to want is a complete own topic and too broad to be handled in a single question.

How to cast explicitly in clojure when interfacing with java

In trying to use weka from clojure, I'm trying to convert this howto guide from the weka wiki to clojure using the java interop features of clojure.
This has worked well so far, except in one case, where the clojure reflection mechanism can't seem to find the right method to invoke - I have:
(def c-model (doto (NaiveBayes.) (.buildClassifier is-training-set)))
Later this will be invoked by the .evaluateModel method of the Evaluation class:
(.evaluateModel e-test c-model is-testing-set)
where e-test is of type weka.classifiers.Evaluation and, according to their api documentation the method takes two parameters of types Classifier and Instances
What I get from clojure though is IllegalArgumentException No matching method found: evaluateModel for class weka.classifiers.Evaluation clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53) - I guess that this is because c-model is actually of type NaiveBayes, although it should also be a Classifier - which it is, according to instance?.
I tried casting with cast to no avail, and from what I understand this is more of a type assertion (and passes without problems, of course) than a real cast in clojure. Is there another way of explicitly telling clojure which types to cast to in java interop method calls? (Note that the original guide I linked above also uses an explicit cast from NaiveBayes to Classifier)
Full code here: /http://paste.lisp.org/display/129250
The linked javadoc contradicts your claim that there is a method taking a Classifier and an Instances - what there is, is a method taking a Classifier, an Instances, and a variable number of Objects. As discussed in a number of SO questions (the only one of which I can find at the moment is Why Is String Formatting Causing a Casting Exception?), Clojure does not provide implicit support for varargs, which are basically fictions created by the javac compiler. At the JVM level, it is simply an additional required parameter of type Object[]. If you pass a third parameter, an empty object-array, into your method, it will work fine.
IllegalArgumentException No matching method found happens anytime the arguments don't match the class. They can fail to match because no method exists with that name and number of arguments or because no method exists with that name in the called class. so also check the number and type of the arguments.
I basically always resort to repl-utils/show in these cases

Eclipse how to convert automatically?

Say I have:
p.size = packetLine[0]; // where packetLine is of type String[] and element at that position is number represented by String
I don't want always to write
Integer.parseInt
or reverse
String.valueOf
Eclipse gives propositions to correct the error, can I make it to advice to convert the values?
At the moment it suggests to change the type. I would like third proposition 'Convert to Int' or 'Convert to String;
This is particularly annoying when repeating thousand times, I might just introduce my own method for converting like toInt or toString2, but in build solution would be better.
Yup, you're stuck with either a method on your class (toInt() like you suggested) or a static utility method. (Which is nice, if you prefer not to have lots of try/catch, you can choose to return 0 for malformed integers. Or whatever is appropriate. I like 0 instead of exception.)
The only "built-in" casting is turning anything to a String (with its toString() method), during concatenation. Like,
String s = "as a string, it is: " + anything; // and null becomes "null".
Sometimes you see this:
String s = "" + something; // shorthand
(Numeric types are implicitly cast for you, too. But mostly you're supposed to be type safe and all that.)
What you are asking for is not casting. Java uses the term casting for two operations:
Converting a numeric primitive to another numeric primitive by approximating the original value as much as possible e.g. int to double.
Storing the contents of an object reference variable to a more specific reference variable, if and only if the referred object can actually be stored there.
What you are asking for is conversion from String to a primitive type and vice versa. It does not usually make sense to provide shortcuts for this. There are more than one ways to do it and none is universal. E.g. a numeric String can be interpreted as an octal or a hexadecimal number and a float can be converted to a String with a varying number of floating point digits, depending on the required precision...
EDIT:
You might be able to make your life easier with repeated operations by creating custom editor templates in Eclipse. Editor templates are accessible along with the rest of the content assist proposals when you press Control+Space. Template creation is not always straightforward, but it can be quite helpful in some cases.
You can't add implicit casts in java, as the language doesn't support it, outside of primitive types / class hierarchies.

Why does Jalopy format my Java code this way?

When I type an entry for an array in java this way, Jalopy (an alternate program to Jindent) switches the square bracket to the other side. Am I typing the wrong way or what?
Before formatting:
After formatting:
Using square bracket after variable name is old style of C,C++. While placing it with the type name is recommended by Java. It is specific to java code style. Since Jalopy is specifically there to format java Code it uses recommended Java style to format. and Hence the code is changing.
Consistency for one, I guess.
And more importantly to make the types clearer. Java (similar to C, I think) allows the [] to appear after either the type or identifier (or even both, being the equivalent of [][]). Putting them after the type makes very clear what the actual type is, because nickFreq is an int[], not an int.
If you prefer the old C-style, you can configure it in your settings, see here:
http://www.triemax.com/products/jalopy/manual/java.html#ARRAY_BRACKETS_AFTER_IDENT
It gets quite interessting when it comes to multi-dimensional arrays...

How to pass a typed collection from clojure to java?

I know the basics of clojure/java interop: calling java from clojure and vice versa. However, I was not able to return a typed collection from clojure to java. I am trying to see something of that nature List<TypedObject> from the java code which is calling into clojure.
Java Object:
public class TypedObject {
private OtherType1 _prop1;
public OtherType1 getProp1() {
return _prop1;
}
public void setProp1(OtherType1 prop1) {
_prop1 = prop1;
}
}
CLojure method:
(defn -createListOfTypedObjects
"Creates and returns a list of TypedObjects"
[input]
;Do work here to create and return list of TypedObjects
[typedObj1, typedObj2, typedObj3])
(:gen-class
:name some.namespace
:methods [createListofTypedObjects[String] ????])
Let us consider that I am writing an API using clojure, which is to be distributed as a jar file, to be used from java. My question was really how to what to pass in place of the ???? questions marks above inside the :gen-class for AOT, so that a programmer writing a piece of code in java using my api, can have the appropriate intellisense / code completion (i.e.: createListofTypedObjects() returns List<TypedObject>) from within eclipse for example.
The others are right that Clojure doesn't ensure the types of elements in returned collections, etc. (Actually, the JVM doesn't ensure the types of elements in collections, either – that's handled entirely by javac.)
However, I can see the value of providing an API to other Java programmers that specifies an interface that declares that return values (or parameters) parameterized in various ways; this is especially attractive if one is looking to use Clojure in an existing Java environment without making waves.
This currently requires a two step process:
define a separate interface (in Java!) that specifies the parameterized types as you like
define your gen-class namespace (or proxy or reify instance) such that it implements that interface
(Clojure does provide a definterface form that would allow you to avoid the separate Java interface definition, but definterface, just like the rest of Clojure, does not provide for specifying parameterized types. Maybe someday... :-))
e.g.
public interface IFoo {
List<TypedObject> createListOfTypedObjects ();
}
and then your gen-class namespace:
(ns your.ns.FooImpl
(:gen-class
:implements [IFoo]))
(defn -createListOfTypedObjects
[]
[typedObj1, typedObj2, typedObj3])
When your users create instances of FooImpl, they'll e.g. get code completion indicating that the method returns List<TypedObject> rather than Object or the unparameterized List type.
If you're using sane build tools (e.g. maven, gradle, or properly-configured ant), then you can put the Java interface in your Clojure project, and the cross-language dependency will be taken care of.
If you're trying to pass something like List<String> to a java method, then you don't need to worry about it. The type parameter (e.g., String) is only used to by the javac compiler, so any List will work just fine at runtime.
On the other hand if you're trying to pass an array of a particular object type (e.g., String[]), then you can use the various -array functions:
user=> (make-array String 10) ; an empty String array
#<String[] [Ljava.lang.String;#78878c4c>
user=> (into-array ["foo" "bar"]) ; array type inferred from first element
#<String[] [Ljava.lang.String;#743fbbfc>
user=> (into-array Number [1.2 5 7N]) ; explicit type array
#<Number[] [Ljava.lang.Number;#7433b121>
You don't need to worry about generics (typed collections) in Clojure. Generics are really just type hints to the Java compiler. In a running Java program, List<String> is effectively the same as List<Object>.
So, for example, a Clojure vector containing Strings is already a List<String> with no conversion needed.

Categories