I've recently given Scala a second chance, and started with the project I always implement (in functional or pseudo-functional languages): an automated reasoner for propositional logic (and later predicate logic).
Now, I've tried to get the notation of propositional logic in the language itself as pretty as possible, and I've gotten this far - with an implicit conversion (String -> Atom):
("A" and "B") implies "C"
The functions "and" and "implies" (and "or" and "equivalent") are simple methods that call the relevant case class constructor. However, when implementing "not", I get stuck with either of the two following notations:
("A" and "B").not
Not("A" and "B")
Is there a way to trick Scala into accepting the desired:
not("A" and "B")
Preferrably without renaming the class "Not" to "not", because I might like to call it "¬" or something else, in th future.
As of Feb 2014, I think the cleanest way to define a prefix'ish not
operation on expressions, while avoiding all sorts of extra cruft/wrapping, would be to declare the function directly in the package scope, together with all your other functions, classes, types etc: This is done by defining a package object (Scala doesn't allow you to just put functions at the root level of the .scala
file (I'd love to learn why—is it just to follow Java's footsteps?)).
package org.my.logiclib
implicit class Atom(s: String) { ... }
class MyType1
class MyType2
object `package` {
def not(expr: Expr) = ...
}
this way, doing import org.my.logiclib._
will import everything, including not()
.
The above is the same as
package org.my
package logiclib {
implicit class Atom ...
...
def not(expr: Expr) = ...
}