How to create a function or operator using a symbol? - r

I would like to create a function with a symbol (for instance, ~), which works similarly to the "question mark" function.

You can't do something as "bare" as ?foo without messing with the C code that defines the syntax of R. For example, you can't make [fnord be meaningful.
This comes from the syntax definition in gram.y in the R sources.
| '~' expr %prec TILDE { $$ = xxunary($1,$2); }
| '?' expr { $$ = xxunary($1,$2); }
| expr ':' expr { $$ = xxbinary($2,$1,$3); }
| expr '+' expr { $$ = xxbinary($2,$1,$3); }
The second line above defines the syntax for ?foo. What exactly are you trying to do?

You can make functions and variables with arbitrary names, via use of the backtick `.
`~` <- `+`
y <- 5
x <- 10
y ~ x
# 15
I wouldn't mess with ~ though, unless you don't intend to do any statistical modelling....

Related

OCaml map not updating before the next step in a sequence

I am trying to implement a basic parser, scanner, and a minimal language in OCaml. I believe the issue is that I'm trying to maintain a map between variables in this toy language and their values, and the language should be able to handle an expression like a=2;a and return 2. The name seems to successfully store the number 2, but by the time the program moves on to evaluating the second expression, it does not find the name in the map. And I can't understand why.
Below is the abstract syntax tree.
Ast.ml
type operator = Add (* for now just one operator *)
type expr =
Binop of expr * operator * expr
| Lit of int (* a number *)
| Seq of expr * expr (* a sequence, to behave like ";" *)
| Asn of string * expr (* assignment, to behave like "=" in an imperative language *)
| Var of string (* a variable *)
Here are the parser and scanner.
parser.mly
%{
open Ast
%}
%token SEQ PLUS ASSIGN EOF
%token <int> LITERAL
%token <string> VARIABLE
%left SEQ PLUS
%start expr
%type <Ast.expr> expr
%%
expr:
| expr SEQ expr { Seq($1, $3) }
| expr PLUS expr { Binop($1, Add, $3) }
| LITERAL { Lit($1) }
| VARIABLE { Var($1) }
| VARIABLE ASSIGN expr { Asn($1, $3) }
scanner.mll
{
open Parser
}
rule tokenize = parse
[' ' '\t' '\r' '\n'] { tokenize lexbuf }
| '+' { PLUS }
| ['0'-'9']+ as lit { LITERAL(int_of_string lit) }
| ['a'-'z']+ as id { VARIABLE(id) }
| '=' { ASSIGN }
| ';' { SEQ }
| eof { EOF }
And here's where I tried to implement a sort of name-space in a basic calculator.
calc.ml
open Ast
module StringMap = Map.Make(String)
let namespace = ref StringMap.empty
let rec eval exp = match exp with
| Lit(n) -> n
| Binop(e1, op, e2) ->
let v1 = eval e1 in
let v2 = eval e2 in
v1+v2
| Asn (name, e) ->
let v = eval e in
(namespace := StringMap.add name v !namespace; v)
| Var(name) -> StringMap.find name !namespace
| Seq(e1, e2) ->
(let _ = eval e1 in
eval e2)
let _ =
let lexbuf = Lexing.from_channel stdin in
let expr = Parser.expr Scanner.tokenize lexbuf in
let result = eval expr in
print_endline (string_of_int result)
To test it out I compile, and it compiles successfully, then run $ ./calc in a terminal, and enter a=2;a then press Ctrl+D. It should print 2 but it gives a Not found exception. Presumably this is coming from the StringMap.find line, and it's not finding the name in the namespace. I've tried throwing print lines around, and I think I can confirm that the sequence is being correctly processed in the terminal and that the first evaluation is happening successfully, with the name and value getting entered into the string map. But for some reason it seems not to be there when the program moves on to processing the second expression in the sequence.
I'd appreciate any clarification, thanks.
I cannot reproduce your error.
Feeding the AST directly to eval
let () =
let ast = Seq(Asn ("a", Lit 2),Var "a") in
let result = eval ast in
print_endline (string_of_int result)
prints 2 as expected.
After fixing your parser to recognize the end of the stream:
entry:
| expr EOF { $1 }
using it in
let () =
let s = Lexing.from_string "a=2;a\n" in
let ast = Parser.entry Scanner.tokenize s in
let result = eval ast in
print_endline (string_of_int result)
prints 2 as expected. And without this fix, your code fails with a syntax error.
EDIT:
Rather than using a makefile, I will advise to use dune, with the following simple dune file:
(menhir (modules parser))
(ocamllex scanner)
(executable (name calc))
it will at least solve your compilation troubles.
Hey so I don't know if you are still looking for the solution, but I was able to reproduce the problem and how I solved it was simply adding assign to the %left statement in parser.mly
%left SEQ ASSIGN PLUS

Using invalid character "²" for squared. Extend Julia syntax with custom operators

In my equations we have many expressions with a^2, and so on. I would like to map "²" to ^2, to obtain something like that:
julia> a² == a^2
true
The above is not however a legal code in Julia. Any idea on how could I implement it ?
Here is a sample macro #hoo that does what you requested in a simplified scenario (since the code is long I will start with usage).
julia> x=5
5
julia> #hoo 3x² + 4x³
575
julia> #macroexpand #hoo 2x³+3x²
:(2 * Main.x ^ 3 + 3 * Main.x ^ 2)
Now, let us see the macro code:
const charsdict=Dict(Symbol.(split("¹²³⁴⁵⁶⁷⁸⁹","")) .=> 1:9)
const charsre = Regex("[$(join(String.(keys(charsdict))))]")
function proc_expr(e::Expr)
for i=1:length(e.args)
el = e.args[i]
typeof(el) == Expr && proc_expr(el)
if typeof(el) == Symbol
mm = match(charsre, String(el))
if mm != nothing
a1 = Symbol(String(el)[1:(mm.offset-1)])
a2 = charsdict[Symbol(mm.match)]
e.args[i] = :($a1^$a2)
end
end
end
end
macro hoo(expr)
typeof(expr) != Expr && return expr
proc_expr(expr)
expr
end
Of course it would be quite easy to expand this concept into "pure-math" library for Julia.
I don't think that there is any reasonable way of doing this.
When parsing your input, Julia makes no real difference between the unicode character ² and any other characters you might use in a variable name. Attempting to make this into an operator would be similar to trying to make the suffix square into an operator
julia> asquare == a^2
The a and the ² are not parsed as two separate things, just like the a and the square in asquare would not be.
a^2, on the other hand, is parsed as three separate things. This is because ^ is not a valid character for a variable name and it is therefore parsed as an operator instead.

pyparsing not parsing the whole string

I have the following grammar and test case:
from pyparsing import Word, nums, Forward, Suppress, OneOrMore, Group
#A grammar for a simple class of regular expressions
number = Word(nums)('number')
lparen = Suppress('(')
rparen = Suppress(')')
expression = Forward()('expression')
concatenation = Group(expression + expression)
concatenation.setResultsName('concatenation')
disjunction = Group(lparen + OneOrMore(expression + Suppress('|')) + expression + rparen)
disjunction.setResultsName('disjunction')
kleene = Group(lparen + expression + rparen + '*')
kleene.setResultsName('kleene')
expression << (number | disjunction | kleene | concatenation)
#Test a simple input
tests = """
(8)*((3|2)|2)
""".splitlines()[1:]
for t in tests:
print t
print expression.parseString(t)
print
The result should be
[['8', '*'],[['3', '2'], '2']]
but instead, I only get
[['8', '*']]
How do I get pyparsing to parse the whole string?
parseString has a parameter parseAll. If you call parseString with parseAll=True you will get error messages if your grammar does not parse the whole string. Go from there!
Your concatenation expression is not doing what you want, and comes close to being left-recursive (fortunately it is the last term in your expression). Your grammar works if you instead do:
expression << OneOrMore(number | disjunction | kleene)
With this change, I get this result:
[['8', '*'], [['3', '2'], '2']]
EDIT:
You an also avoid the precedence of << over | if you use the <<= operator instead:
expression <<= OneOrMore(number | disjunction | kleene)

Rewrite recursive BNF rule with iteration

Look at the following recursive BNF rule
(1) X = Xa | b
This produces sentences like
X = b
X = ba
X = baa
X = baaa
...
This can be written as
(2) X = b a*
where the right hand side is not recursive
Now take a look at the following recursive BNF rule
(3) X = { X } | b
This produces sentences like
X = b
X = {b}
X = {{b}}
X = {{{b}}}
...
Is there some way to rewrite rule (3) in a non recursive way, analogous as we did when we rewrote rule (1) to rule (2).
Observe that X = {* b }* is no good since the parenthesis need to be balanced.
I do not know if the question above is possible to answer. The reason for the question above was that I wanted to avoid infinite loop in my parser (written in Java). One way was to insure that the BNF rules are not recursive, hence my question. But another way is to use the recursive rule, but avoid the infinite loop inside my (Java) program. Turns out that you can avoid loops by lazy instantiation.
For instance look at the following rules:
expression = term ('+' term)*;
term = factor ('*' factor)*;
factor = '(' expression ')' | Num;
expression() calls term(), which calls factor(), which calls expression(), thus we can end up with infinite loop. To avoid that we can use lazy instantiation, so instead of writing something like:
public Parser expression() {
expression = new ...
return expression;
}
we instead write:
public Parser expression() {
if (expression == null) {
expression = new ...
}
return expression;
}
Observe that you must declare expression as an instance variable to get this to work.

expression syntax for data.table := in R

I am having some trouble getting an eval within data.table in R to work with an expression. Here is some code:
dtb = data.table(a=1:100, b=100:1, id=1:10)
dtb[,`:=`(c=a+b, d=a/b),by=id] #this works fine
expr = expression({`:=`(c=a+b, d=a/b)}) #try to couch everything in an expression
dtb[,eval(expr),by=id] #this does not work
Error in `:=`(c = a + b, d = a/b) :
unused argument(s) (c = a + b, d = a/b)
expr = expression(`:=`(c=a+b, d=a/b)) #this works fine
dtb[,eval(expr),by=id]
Why does including {} break this?
See the definition of :=:
function (LHS, RHS)
stop(":= is defined for use in j only, and (currently) only once; i.e., DT[i,col:=1L] and DT[,newcol:=sum(colB),by=colA] are ok, but not DT[i,col]:=1L, not DT[i]$col:=1L and not DT[,{newcol1:=1L;newcol2:=2L}]. Please see help(\":=\"). Check is.data.table(DT) is TRUE.")
The assignment of a column doesn't happen within a call of :=--the function itself doesn't do anything besides produce an error. The assignment happens when [.data.table detectsj is an expression of the form `:=`(...) and then sets everything up for a call to the C code. When you enclose expr in brackets, you're making the first part of the expression { instead of :=, which passes by the above detection and eventually results in an evaluation of := with arguments c and d.
I guess that leads to the question, why do you need to enclose it in { }?
Issue #376 to trap the { around := has now been implemented in v1.8.11. From NEWS:
o FR #2496 is now implemented to trap and remove the { around := in j to obtain desired result. Now, DT[,{`:=`(...)}] and DT[, {`:=`(...)}, by=(...)] both work as intended but with a warning. Thanks to Alex for reporting on SO: expression syntax for data.table := in R

Resources