Maybe use {} interpolation syntax, e.g., “Welcome to {$location.city}!”
We need to have an entry in the type context for all the fields of the context macros in the program. Such entries are just trees with the types at the leaves.By this I mean a checker that checks whether every branch of the program has the correct assignments.
I think this is due to reliance on the Text.Parsec.Token lexer, which considers
a linebreak white space to be ignored. Needs to be confirmed. See for example
the programs minimalParseFailure, counterExample1 and counterExample2 in
TreeLang.Examples.
If my hypothesis is correct, there seem to be two angles of attack for this issue:
- make use of indent parser, to make the language fully indentation sensitive
- write a lexer from scratch (by copy-pasting from Text.Parsec.Token)
This would allow for easy concurrent data access.
The language should have a good concept of unknowns. Dereferencing the context macros might fail.
This is very preliminary. I am thinking of something like title = [{"Welcome!",
"Hey!"}|gender], to automatically select the title from the two
options given based on the gender.
feature/add-functions
This would entail
data Expr
= ContextMacro [Expr] String
...in which the list of expressions are the arguments to the function (it might also be a map of expressions, if named arguments are required: I think it is better for it to be a map, since that would make it easier to implement generic datasources. Just serialize the map to JSON and post it to the supplied resource).
Then the lookupObj function would need to return a function from [Expr] to
(ContextObj Expr).
It would now also be better to have GADTs restrict the type of the expression to passed in. We could then partition the Expr’s into Values and Reducibles, and have the Haskell type checker ensure that only values are passed to the context macro.
It would now be best to have the type checker to know about functions (with named arguments, if arguments to context macros are passed as maps).
If so, how can we specify them as YAML for instance. Pros:
- For some it might be necessary, e.g., ad-hoc bandit context objects, and for others it isn’t, e.g. weather, location.
Cons: -
For istance, stuff that comes out of the request. I think the best thing would
be to treat them on the same level as other context objects. So maybe something like,
$request.ip_address, $request.user_agent are valid context objects.
Types only change when releasing context services.
Change dynamically.
We use Python syntax highlighting for tree-lang, since the syntax is meant to be similar.
This is a program that we eventually should be able to execute. It requires a number of features not yet available.
- placeholder declarations (with types)
- random choice as a context object
- local variables (e.g. group)
- string interpolation
- reference types (i.e., those starting with @)
- lists
# This is an example of what a tree-lang program could eventually look like.
# To evaluate it, the interpreter expects the following objects to be in context:
# weather, product[most_clicked], product[most_seen], random, selector[cta_per_day].
#
# To reduce the possibility of mistakes we need:
#
# - good previews
#
# - a type checker with dynamically provided types (at least for the ad-hoc
# context objects, such as product[most_clicked].
placeholder pancake: image = @default_pancake
placeholder title: text = "Default title"
placeholder cta: text = "Default CTA"
placeholder background: image = @"background-{$creative.size}"
placeholder cube: image[] = [@generic_product]
placeholder color: color = $template.placeholder.color
group = random[A=1, B=1, C=1].value
if group == "A":
if $weather.condition in ["rainy", "cloudy"]:
pancake = @rainy_background
cube = product[most_clicked]($turbine.segment, $weather.condition, limit=2) + \
product[most_seen]($turbine.segment, limit=2)
if $device.touch_screen:
cta = "Tap me"
else:
cta = selector[cta_per_day_part]($time.cta_per_day_part)
end
else:
pancake = @sunny_background
end
elif group == "B":
title = "Our most generic product"
cta = "Buy me!"
end