SlideShare uma empresa Scribd logo
1 de 200
Baixar para ler offline
Scala meta-DSL for Datomic
Marc Grue
April 2017
Molecule
Molecule
Introduction to Datomic
Building a DSL with Scala macros
Tour of Molecule features
Molecule and domain modelling
2
3
1
4
Molecule
• Facts
• Entities
• Immutability
• Time
• Architecture
1
Datomic
Molecule
Key-Value
32 pizza
Molecule
Fact
Fred likes pizza
Molecule
Fact
Entity Attribute Value
Fred likes pizza
Molecule
Fact
Entity Attribute Value Time
Fred likes pizza 10:31
Molecule
Fact
Entity Attribute Value Time Op
Fred likes pizza 11:16 retract
Molecule
Datom
Entity Attribute Value Tx (time) Operation
fred (eid) likes pizza tx4 assert/retract
Molecule
Datom
fred likes pizza tx4 assert/retract
E A V T Op
Molecule
Datom
fred :person/likes pizza tx4 assert/retract
E A V T Op
Namespace
Molecule
Schema of attributes
eid :person/likes String value … …
E A V T Op
{":db/ident" ":person/likes"}
Attribute Value
Molecule
Schema of attributes
eid :person/likes String value … …
E A V T Op
string
boolean
long
bigint
float
double
big dec
ref
instant (date)
uuid
uri
bytes
keyword (enum)
Types
{":db/ident" ":person/likes"
":db/valueType" ":db.type/string"}
Molecule
Schema of attributes
eid :person/likes String value … …
E A V T Op
one
many
Cardinality{":db/ident" ":person/likes"
":db/valueType" ":db.type/string"
":db/cardinality" ":db.cardinality/one"}
Molecule
Schema of attributes
eid :person/likes String value … …
E A V T Op
{":db/ident" ":person/likes"
":db/valueType" ":db.type/string"
":db/cardinality" ":db.cardinality/one"
":db/doc" "What a Person likes"} doc
unique/value
unique/identity
index
fulltext
isComponent
noHistory
Options
Molecule
101 :person/name Fred
101 :person/likes pizza
101 :person/age 38
101 :person/addr 102
Common entity id
Entity
Molecule
Entity
101 :person/name Fred
101 :person/likes pizza
101 :person/age 38
101 :person/addr 102
101 :site/cat customer
Common entity id
Entities can span any attributes!
Molecule
Entity
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:person/addr 102
:site/cat customer
Group of facts with shared entity id
Molecule
Relationships
eid 102
:addr/street Baker st.
:addr/zip 90221
:site/cat identifier
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:person/addr 102
:site/cat customer
Molecule
Relationships
eid 104
:person/name Ben
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:person/kids 103, 104
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
Molecule
fred :person/likes pizza tx4 (10:31) assert
Mutable
E A V T Op
Immutable facts
Id likes
fred pizza
… …
Person table
{ id: fred
likes: “pizza” }
Person document
Molecule
Id likes created
fred pizza 10:31
… … …
Person table E A V T Op
fred :person/likes pizza tx4 (10:31) assert
Create Assert
{ id: fred
likes: “pizza”
created: “10:31” }
Person document
Molecule
fred :person/likes pizza tx5 (12:45) retract
fred :person/likes pasta tx5 (12:45) assert
Id likes created updated
fred pasta 10:31 12:45
… … …
fred :person/likes pizza tx4 (10:31) assert
Update
Person table
Retract-Assert
Person document
{ id: fred
likes: pasta
created: “10:31”
updated: “12:45” }
E A V T Op
Molecule
fred :person/likes pasta tx6 (17:10) retract
fred :person/likes pizza tx5 (12:45) retract
fred :person/likes pasta tx5 (12:45) assert
Id likes created updated
fred NULL 10:31 17:10
… … …
Delete
Person table
Retract
E A V T Op
Person document
{ id: fred
likes: null
created: “10:31”
updated: “17:10” }
fred :person/likes pizza tx4 (10:31) assert
Molecule
101 :person/likes pizza tx4 (10:31) assert
101 :person/likes pizza tx5 (12:45) retract
101 :person/likes pasta tx5 (12:45) assert
101 :person/likes pasta tx6 (17:10) retract
Read
E A V T Op [:find ?v
:where
[101 :person/likes ?v]]
=> Nil (no current likes)
Molecule
101 :person/likes pizza tx4 (10:31) assert
101 :person/likes pizza tx5 (12:45) retract
101 :person/likes pasta tx5 (12:45) assert
101 :person/likes pasta tx6 (17:10) retract
asOf
E A V T Op [:find ?v
:in db.asOf(tx5)
:where
[101 :person/likes ?v]]
=> [pasta]
Molecule
101 :person/likes pizza tx4 (10:31) assert
101 :person/likes pizza tx5 (12:45) retract
101 :person/likes pasta tx5 (12:45) assert
101 :person/likes pasta tx6 (17:10) retract
History
E A V T Op [:find ?v ?t ?op
:in db.history
:where
[101 :person/likes ?v ?t ?op]]
=> [pizza tx4 assert ]
[pasta tx5 retract]
[pasta tx5 assert ]
[pasta tx6 retract]
Molecule
101 :person/likes pizza tx1 assert
102 :person/likes pasta tx2 assert
103 :person/likes sushi tx3 assert
104 :person/likes burger tx4 assert
Since
E A V T Op [:find ?v
:in db.since(tx2)
:where
[?e :person/likes ?v]]
=> [sushi burger]
(updated slide)
Molecule
101 :person/likes pizza tx4 (10:31) assert
101 :person/likes pizza tx5 (12:45) retract
101 :person/likes pasta tx5 (12:45) assert
101 :person/likes pasta tx6 (17:10) retract
With (the future!)
E A V T Op [:find ?v
:in db.with(testDataTx)
:where
[101 :person/likes ?v]]
=> [penne]
101 :person/likes penne tx7 assert
testDataTx = { id: 101
likes: “penne” }
As though we had created this fact
Molecule
Datomic
architecture
Expensive connection
App process (JVM)
App
All-in-one Database server
Molecule
App process (JVM)
Datomic
architectureApp
Peer
Transactor
• Separating Reads and writes in 2
processes!
• Peer lib in your app process
• Multiple Peers possible
• Not a client-server (optional)
• No network traffic
Reads
Writes
Molecule
App process (JVM)
Datomic
architectureApp
Peer
Query
Transactor
Transactions Storage Service
• In-memory
• SQL
• DynamoDB
• Cassandra
Reads
Writes
Molecule
App process (JVM)
Datomic
architectureApp
Peer
Commit
Query
Cache
Transactor
Transactions Storage Service
Molecule
App process (JVM)
Datomic
architectureApp
Peer
Commit
Query
Live Index
Cache
Transactor
TransactionsIndexing Storage Service
Molecule
App process (JVM)
Datomic
architectureApp
Peer
Commit
Query
Live Index
Cache
Transactor
TransactionsIndexing Storage Service
Memcached cluster
Molecule
Datomic
2
Molecule
[:find ?name ?age
:where
[?e :person/name ?name]
[?e :person/age ?age]]
Molecule
[:find ?name ?age
:where
[?e :person/name ?name]
[?e :person/age ?age]]
Molecule
[:find ?name ?age
:where
[?e :person/name ?name]
[?e :person/age ?age]]
Molecule
Molecule
(Previously `Seq`)
Molecule
Molecule
Molecule
Molecule
Macro should create this:
Molecule
Molecule
Molecule
Molecule
Molecule
Molecule
Molecule DSL
Molecules
Your domain terms
Namespace "Person"
Molecule
Molecule DSL
Molecules
Your domain terms
Namespace "Person"
Attribute :person/name
Person1[String]
Molecule
Molecule DSL
Molecules
Your domain terms
Namespace "Person"
Attribute :person/name
Person1[String]
No need to implement
here - macro
implements!


Only the return type is
needed!
Molecule
Molecule DSL
Molecules
Your domain terms
Namespace "Person"
Attribute :person/name
Person1[String]
Attribute :person/age
Person2[String, Int]
Molecule
Molecule DSL
MoleculesRuntime API
M2[String, Int]
Returns Seq[(String, Int)]
Molecule
Molecule DSL
MoleculesRuntime API
M2[String, Int]
Returns Seq[(String, Int)]
Implemented by macro
Molecule
Molecule
Molecule DSL
Molecules
A lot of redundant boilerplate code!
Molecule
Schema definition
Molecule DSL
SBT plugin generates
Molecules
Molecule
Schema definition
Molecule DSL
SBT plugin generates
Molecules
Namespaces
Molecule
Schema definition
Molecule DSL
SBT plugin generates
Molecules
Attributes
Molecule
Schema definition
Molecule DSL
SBT plugin generates
Molecules
Cardinality /Types
Molecule
Schema def DSL
Schema definition
Molecule DSL
SBT plugin generates
Molecules
Card/type
oneString
manyString
oneInt
manyInt
one[Address]
many[InvoiceLine]
...
Molecule
Schema def DSL
Schema definition
Molecule DSL
SBT plugin generates
Molecules
oneString.fulltext.doc("name of person")
manyString
oneInt.doc("age of person")
manyInt
one[Address]
many[InvoiceLine].subComponents
etc...
Card/type
Options
Molecule
Define
schema
Sbt compile
(once)
Molecule
DSL
Datomic
DSL
Compose
Molecules
Get/Set

Datomic
Data
Compile
Run
Schema
definition
DSL
Molecule eco system
Molecule
Define
schema
Sbt compile
(once)
Molecule
DSL
Datomic
DSL
Compose
Molecules
Get/Set

Datomic
Data
Compile
Run
Schema
definition
DSL
You'll be here most of the time
Molecule eco system
Molecule
Define
schema
Sbt compile
(once)
Molecule
DSL
Datomic
DSL
Compose
Molecules
Get/Set

Datomic
Data
Compile
Run
Schema
definition
DSL
A DSL to create
a DSL to create
a DSL
... must be a meta-DSL, no?
You'll be here most of the time
Molecule eco system
Tour...
Molecule
3
Molecule
Core
• Entities
• Attributes
• Expressions
• Relationships
• Composites
• CRUD
Extras
• Map attributes
• Input molecules
• Bidirectional refs
Time
• Tx data
• Tx meta data
• asOf
• history
• since
• with
Molecule
Entitieseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
Groups of facts with common entity id
Molecule
Entitieseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
Groups of facts with common entity id
How can we know what facts are grouped at runtime?
- the schema doesn't tell us...
Molecule
Entitieseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
Entity API
Molecule
Entitieseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
Entity API
Molecule
Attributes
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
Ns.attr --> :ns/attr
"Person names"
Molecule
Attributes
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
Ns.attr.attr2... -->
:ns/attr
:ns/attr2
...
"Person names and ages"
Molecule
Attributes
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7 "Person names, ages and likes"
Molecule
Attributes
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
• Mandatory ("attr")
• Fact exists
• Value is returned
• Tacet
• Optional"Person names, ages and likes"
Molecule
Attributes
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
• Mandatory ("attr")
• Fact exists
• Value returned
• Tacet ("attr_")
• Fact exists
• Value not returned
• Optional
"Names and ages of Persons that like something"
Molecule
Attributes
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
• Mandatory ("attr")
• Fact exists
• Value returned
• Tacet ("attr_")
• Fact exists
• Value not returned
• Optional ("attr$")
• Fact may exists
• Option[Value] returned
"Names, ages and possibly likes of Persons"
Molecule
Expressions
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
• Equality
• Fulltext search
• Negation
• Null / Nil
• Comparison
• Aggregates
• Logical OR
"Names and likes of Persons that likes pizza"
Molecule
Expressions
• Equality + tacet
• Fulltext search
• Negation
• Null / Nil
• Comparison
• Aggregates
• Logical OR
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
"Names of persons that like pizza"
Molecule
Expressions
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred Ben
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
• Equality
• Fulltext search
• Negation
• Null / Nil
• Comparison
• Aggregates
• Logical OR
Molecule
Expressions
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
• Equality
• Fulltext search
• Negation
• Null / Nil
• Comparison
• Aggregates
• Logical OR
Molecule
Expressions
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
• Equality
• Fulltext search
• Negation
• Null / Nil
• Comparison
• Aggregates
• Logical OR
"Names of Persons that haven't stated what
they like"
:person/likes fact not asserted for Lisa
- or it has been retracted!
Molecule
Expressions
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
• Equality
• Fulltext search
• Negation
• Null / Nil
• Comparison
• Aggregates
• Logical OR
Molecule
Expressions
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
• Equality
• Fulltext search
• Negation
• Null / Nil
• Comparison
• Aggregates
• Logical OR
"Minimum age of all persons"
"Count of all persons with an age asserted"
"Average age of persons (with age asserted)"
Molecule
Expressions
eid 104
:person/name Ben
:person/likes pizza
:person/age 5
eid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
eid 103
:person/name Lisa
:person/age 7
• Equality
• Fulltext search
• Negation
• Null / Nil
• Comparison
• Aggregates
• Logical OR
"Names and ages of Persons that are 5, 6 or 7
years old"
Molecule
Relationships
• Card-one
• Card-many
Defining relationships in schema definition
Molecule
Relationships
• Card-one
• Card-many
Molecule
Relationships
• Card-one
• Card-many
eid attr value
- :person/name -
- :person/home -
- :addr/street -
- :addr/city -
Molecule
Relationships
• Card-one
• Card-many
eid attr value
101 :person/name Fred
101 :person/home 102
102 :addr/street Baker St. 7
102 :addr/city Boston
Molecule
Relationships
• Card-one
• Card-many
eid attr value
101 :person/name Fred
101 :person/home 102
102 :addr/street Baker St. 7
102 :addr/city Boston
eid 101
:person/name Fred
:person/home 102
eid 102
:addr/street Baker St. 7
:addr/city Boston
Molecule
Relationships
• Card-one
• Card-many
eid attr value
101 :person/name Fred
101 :person/home 102
102 :addr/street Baker St. 7
102 :addr/city Boston
eid 101
:person/name Fred
:person/home 102
eid 102
:addr/street Baker St. 7
:addr/city Boston
Molecule
Relationships
• Card-one
• Card-many
Molecule
Relationshipseid 101
:person/name Fred
:person/home 102
:person/work 103
• Card-one
• Card-manyeid 102
:addr/street Baker St. 7
:addr/city Boston
eid 103
:addr/street Downtown 1
:addr/city Boston
?
Molecule
Relationshipseid 101
:person/name Fred
:person/home 102
:person/work 103
• Card-one
• Card-manyeid 102
:addr/street Baker St. 7
:addr/city Boston
eid 103
:addr/street Downtown 1
:addr/city Boston
Back reference (2)
1
2
3
Molecule
Relationshipseid 101
:person/name Fred
:person/home 102
:person/work 103
• Card-one
• Card-manyeid 102
:addr/street Baker St. 7
:addr/city Boston
eid 103
:addr/street Downtown 1
:addr/city Boston
Molecule
Relationships
More "arms" to the molecule...
• Card-one
• Card-many
Molecule
Relationships
• Card-one
• Card-many
eid 101
:order/id 1
:order/items 102, 103
eid 102
:lineItem/qty 3
:lineItem/product Milk
:lineItem/price 12.0
eid 103
:lineItem/qty 2
:lineItem/product Coffee
:lineItem/price 46.0
Molecule
Relationships
• Card-one
• Card-many
eid 101
:order/id 1
:order/items 102, 103
eid 102
:lineItem/qty 3
:lineItem/product Milk
:lineItem/price 12.0
eid 103
:lineItem/qty 2
:lineItem/product Coffee
:lineItem/price 46.0
Molecule
Relationships
• Card-one
• Card-many
eid 101
:order/id 1
:order/items 102, 103
eid 102
:lineItem/qty 3
:lineItem/product Milk
:lineItem/price 12.0
eid 103
:lineItem/qty 2
:lineItem/product Coffee
:lineItem/price 46.0
Molecule
Relationships
• Card-one
• Card-many
eid 101
:order/id 1
:order/items 102, 103
eid 102
:lineItem/qty 3
:lineItem/product Milk
:lineItem/price 12.0
eid 103
:lineItem/qty 2
:lineItem/product Coffee
:lineItem/price 46.0
Molecule
Relationshipseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
The black sheep
Molecule
Relationshipseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
No relationship...
Molecule
Relationshipseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:person/site 103
eid 103
:site/cat customer
Molecule
Relationshipseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:person/site 103
eid 103
:site/cat customer
Molecule
Compositeseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
"Names, likes, and ages of Persons
+ their Site category"
Molecule
Compositeseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
Independent &
Intrinsic
Molecule
[:find ?name ?likes ?age ?cat
:where
[?e :person/name ?name ]
[?e :person/likes ?likes]
[?e :person/age ?age ]
[?e :site/cat ?cat ]
]
=> [Fred pizza 38 customer]
Compositeseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
Molecule
[:find ?v1 ?v2 ?v3 ?v4
:where
[?e :xlwk/liawj ?v1]
[?e :iauw/sokqx ?v2]
[?e :kzmm/wwpai ?v3]
[?e :ajdg/tybnq ?v4]
]
Attributes can have any name
Namespaces are not tables
Entity ids tie facts together
Molecule
Compositeseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
Molecule
Compositeseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
:site/status good
"Names, likes, and ages of Persons
+ their Site category and status"
Molecule
Compositeseid 101
:person/name Fred
:person/likes pizza
:person/age 38
:site/cat customer
:site/status good
:loc/tag city
"Names, likes, and ages of Persons
+ their Site category and status
+ their Location tag"
Molecule
• Create
• Save
• Read
• Update
• Delete
CRUD
Molecule
• Create
• Save
• Insert
• Read
• Update
• Delete
CRUD
Molecule
• Create
• Save
• Insert
• 2-step insert
• Read
• Update
• Delete
CRUD
Molecule
• Create
• Save
• Insert
• 2-step insert
• Read
• Update
• Delete
CRUD
Molecule
• Create
• Save
• Insert
• 2-step insert
• Read
• Update
• Card-one
• Delete
CRUD
Molecule
• Create
• Save
• Insert
• 2-step insert
• Read
• Update
• Card-one
• Delete
CRUD
fred :person/likes pizza tx4 assert
fred :person/likes pizza tx5 retract
fred :person/likes pasta tx5 assert
E A V T Op
Molecule
• Create
• Save
• Insert
• 2-step insert
• Read
• Update
• Card-one
• Delete
CRUD
fred :person/likes pizza tx4 assert
fred :person/likes pizza tx5 retract
fred :person/likes pasta tx5 assert
fred :person/likes pasta tx6 retract
E A V T Op
Molecule
• Create
• Save
• Insert
• 2-step insert
• Read
• Update
• Card-one
• Card-many
• Delete
CRUD
Molecule
• Create
• Save
• Insert
• 2-step insert
• Read
• Update
• Card-one
• Card-many
• Delete
CRUD
Molecule
Core
• Entities
• Attributes
• Expressions
• Relationships
• Composites
• CRUD
Extras
• Map attributes
• Input molecules
• Bidirectional refs
Time
• Tx data
• Tx meta data
• asOf
• history
• since
• with
Molecule
Map attributes
Molecule
Map attributes
Molecule
Map attributes
Molecule
Map attributes
Molecule
Input molecules
Molecule
Input molecules
Molecule
Input molecules
Molecule
Bidirectional refs
Molecule
Bidirectional refs
Molecule
Bidirectional refs
Molecule
Bidirectional refs
Molecule
Bidirectional refs
Ann
Ben
Joe
Molecule
Bidirectional refs
Ann
Ben
Joe
Molecule
Bidirectional refs
Ann
:knows/weight 7
Ben
:knows/weight 4
Gus
:knows/weight 6
Joe
Molecule
Core
• Entities
• Attributes
• Expressions
• Relationships
• Composites
• CRUD
Extras
• Map attributes
• Input molecules
• Bidirectional refs
Time
• Tx data
• Tx meta data
• asOf
• history
• since
• with
Molecule
Tx data
e5 :person/name Fred tx4 (10:31) assert
e5 :person/likes pizza tx4 (10:31) assert
E A V T Op
Molecule
Tx data
e5 :person/name Fred tx4 (10:31) assert
e5 :person/likes pizza tx4 (10:31) assert
E A V T Op Magic
tx4?
Molecule
Magic
tx4
Tx data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant 10:31 ...? assert
E A V T Op
Transaction is an entity!
(here with entity id tx4...)
Molecule
Tx data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
E A V T Op
Molecule
Tx data
e5 :person/name Fred e4 assert
e5 :person/likes pizza e4 assert
e4 :db/txInstant date1 e4 assert
E A V T Op
Molecule
Tx data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
E A V T Op
Molecule
Tx data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
E A V T Op
List(
(17592186045445L, :person/name, "Fred", 13194139534340L, true),
(17592186045445L, :person/likes, "pizza", 13194139534340L, true),
(13194139534340L, :db/txInstant, "Tue Apr 26 18:35:41 CEST 2017", 13194139534340L, true)
)
Molecule
Tx data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
E A V T Op
List(
(17592186045445L, :person/name, "Fred", 13194139534340L, true),
(17592186045445L, :person/likes, "pizza", 13194139534340L, true),
(13194139534340L, :db/txInstant, "Tue Apr 26 18:35:41 CEST 2017", 13194139534340L, true)
)
Long clojure.keyword Object (various types) Long Boolean
Molecule
Tx data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
E A V T Op
List(
(17592186045445L, 147L, "Fred", 13194139534340L, true),
(17592186045445L, 148L, "pizza", 13194139534340L, true),
(13194139534340L, 18L, "Tue Apr 26 18:35:41 CEST 2017", 13194139534340L, true)
)
Long Long Object (various types) Long Boolean
Molecule
Tx data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
E A V T Op
In what transaction was
Freds name asserted?
Molecule
Tx data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
E A V T Op
When was Freds name asserted?
Molecule
Tx meta data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
tx4 ... ... tx4 assert
tx4 ... ... tx4 assert
E A V T Op
Molecule
Tx meta data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
tx4 :audit/user Lisa tx4 assert
tx4 ... ... tx4 assert
E A V T Op
Who did it?
Molecule
Tx meta data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
tx4 :audit/user Lisa tx4 assert
tx4 :audit/uc survey tx4 assert
E A V T Op
Who did it?
Why?
Molecule
Tx meta data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
tx4 :audit/user Lisa tx4 assert
tx4 :audit/uc survey tx4 assert
E A V T Op
Who did it?
Why?
Molecule
Tx meta data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
tx4 :audit/user Lisa tx4 assert
tx4 :audit/uc survey tx4 assert
E A V T Op
Who did it?
Why?
"Lisa added Fred as part of a survey"
Molecule
Tx meta data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
tx4 :audit/user Lisa tx4 assert
tx4 :audit/uc survey tx4 assert
E A V T Op
When did they do it?
Who did it?
Why?
"Lisa added Fred as part of a survey
onTuesday the 26th of April"
Molecule
Tx meta data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
tx4 :audit/user Lisa tx4 assert
tx4 :audit/uc survey tx4 assert
E A V T Op
When did they do it?
Who did it?
Why?
"Fred was surveyed"
Molecule
Tx meta data
e5 :person/name Fred tx4 assert
e5 :person/likes pizza tx4 assert
tx4 :db/txInstant date1 tx4 assert
tx4 :audit/user Lisa tx4 assert
tx4 :audit/uc survey tx4 assert
E A V T Op
When did they do it?
Who did it?
Why?
"Lisas surveyee liked pizza"
Molecule
asOf
fred :person/name Fred t1 assert
fred :person/likes pizza t1 assert
E A V T Op
Molecule
asOf
fred :person/name Fred t1 assert
fred :person/likes pizza t1 assert
fred :person/likes pizza t2 retract
fred :person/likes pasta t2 assert
E A V T Op
Molecule
asOf
fred :person/name Fred t1 assert
fred :person/likes pizza t1 assert
fred :person/likes pizza t2 retract
fred :person/likes pasta t2 assert
E A V T Op
"What did Fred like before?"
Molecule
history
fred :person/name Fred t1 TRUE
fred :person/likes pizza t1 TRUE
fred :person/likes pizza t2 FALSE
fred :person/likes pasta t2 TRUE
E A V T Added
API changed from `.history.get` to `.getHistory`
All time filters now have the verb form `get<filter>`
This should avoid confusion with attribute names
Molecule
history
fred :person/name Fred t1 TRUE
fred :person/likes pizza t1 TRUE
fred :person/likes pizza t2 FALSE
fred :person/likes pasta t2 TRUE
E A V T Added
Molecule
history
E A/V T Op
Getting all generic data about the `like` attribute history:
Generic attributes tie to a single domain attribute
Molecule
history
E A V T Op
... or go fully generic and ask for any attribute history of an entity:
Molecule
history
"What has Fred liked?"
Molecule
history
"What has Fred disliked?"
Molecule
history
"Who have disliked what and when?"
Multiple mandatory attributes not allowed in history queries.
It would be like unifying multiple timelines into one timeline
which is not useful.
Molecule
history
"Who have disliked what and when?"
Instead, ask for entity ids with the generic `e`.
Molecule
history + tx meta data
Only one mandatory attribute! ...
Molecule
history + tx meta data
Use generic `e` to get entity id instead.
Molecule
history + tx meta data
"Who changed what taste
during interviews with Peter?"
Molecule
history + tx meta data
"Who changed what taste
during interviews with Peter and when?"
"Who disliked pizza
during an interview and when?"
Molecule
history + tx meta data
Who changed what taste
during interviews with Peter and when?
Who disliked pizza
during an interview and when?
Who liked what and when?
Who got the info in what use case?
Molecule
since
101 :person/likes pizza tx1 TRUE
102 :person/likes pasta tx2 TRUE
103 :person/likes sushi tx3 TRUE
104 :person/likes burger tx4 TRUE
E A V T Added
(updated slide)
Molecule
with
What if ...?
Would that work?
(presented as now deprecated `imagine`)
Molecule
with
What if we update Freds age?
Molecule
with
What if we save a new person?
Molecule
with
What if we insert 2 persons?
Molecule
with
What if we do all 3 things...?
Molecule
with
Test modulerized transactions...
Molecule
Core
• Entities
• Attributes
• Expressions
• Relationships
• Composites
• CRUD
Extras
• Map attributes
• Input molecules
• Bidirectional refs
Time
• Tx data
• Tx meta data
• asOf
• history
• since
• with
3
Questions?
Domain modelling
Molecule
4
Molecule
Person
• id
• name
• born
‣ doThis()
‣ doThat()
Molecule
Person
• id
• name
• born
‣ doThis()
‣ doThat()
‣ ctx1a()
‣ ctx1b()
‣ ctx2a()
Ctx 1
person1.doThis()
person2.ctx1a()
person1.ctx1b()
Ctx 2
person2.ctx2a()
Slow changing
Fast changing
Runtime
Molecule
Person
• id
• name
• born
‣ doThis()
‣ doThat()
‣ ctx1a()
‣ ctx1b()
‣ ctx2a()
‣ ctx2b()
‣ ctx3a()
‣ ctx3b()
‣ ctx4a()
‣ ctx4b()
‣ ctx5a()
‣ ctx5b()
‣ etc...
Ctx 1
person1.doThis()
person2.ctx1a()
person1.ctx1b()
Ctx 2
person2.ctx2a()
Slow changing
Fast changing
Ctx 4
person.ctx4b()
Runtime
Ctx 5
person.ctx5a()
Ctx 3
person.ctx3b()
Ctx 6
person2.ctx6a() C
person2
Molecule
Person
• id
• name
• born
‣ doThis()
‣ doThat()
Ctx 1
customer.doThis()
customer.buy()
Ctx 2
user.login()
Slow changing
Not so fast changing
Ctx 3
manager.add(p1)
Customer
‣ buy()
‣ complain()
User
‣ login()
‣ comment()
Manager
‣ add(person)
‣ getReport()
Faster changing
Runtime
Molecule
Person
• id
• name
• born
‣ doThis()
‣ doThat()
Ctx 1
customer.doThis()
customer.buy()
Ctx 2
user.login()
Slow changing
Not so fast changing
Ctx 3
manager.login()
manager.add(p1)
Customer
‣ buy()
‣ complain()
User
‣ login()
‣ comment()
Manager
‣ add(person)
‣ getReport()
Faster changing
Relatively faster changing
Runtime
Molecule
Person
• id
• name
• born
PersonService(p)
‣ p.doThis()
‣ p.doThat()
‣ p.ctx1a()
‣ p.ctx1b()
‣ p.ctx2a()
‣ etc...
Ctx 1
personService(p1).doThis()
personService(p2).ctx1a()
personService(p1).ctx1b()
Ctx 2
person2.ctx2a()
Fast changing RuntimeSlow changing
Molecule
Person
• id
• name
• born
PersonCmdCtx1(p)
‣ p.ctx1a()
‣ p.ctx1b()
Ctx 1
PersonCmdCtx1(p2).ctx1a()
PersonCmdCtx1(p1).ctx1b()
Ctx 2
PersonCmdCtx2.ctx2a()
PersonCmdCtx2(p)
‣ p.ctx2a()
Slow changing Fast changing Runtime
Molecule
Entity
• id
• attr1
• attr2
• etc...
Slow changing Fast changing
EntityConsumer(e)
‣ action1()
‣ action2()
‣ etc()
• Services
• Event source commands
• Ad hoc classes
• Etc..
Molecule
EntityConsumer(e)
‣ action1()
‣ action2()
‣ etc()
Person
• id
• name
• born
Customer
• status
User
• email
• passw
Manager
• clearance
• employees
Seldom changing
Often changing
Occassionally changing
And more subtypes...
Fast changing
Molecule
EntityConsumer(e)
‣ action1()
‣ action2()
‣ etc()
Person
• id
• born
• name
Customer
• status
User
• email
• passw
Manager
• clearance
• employees
Very seldom changing
Often changing
Occassionally changing
Never changing
And more subtypes...
Fast changing
Molecule
EntityConsumer(e)
‣ changePassw()
Molecular EntitiesAtomic Attributes
Person variations...
eid 101
:person/name
:user/email
:user/passw
:person/id
:person/born
:person/name
:user/email
:user/passw
:site/status
:auth/clearance
:mgt/employees
:mgt/employees
eid 101
:auth/clearance EntityConsumer(e)
‣ authorize(employee)
(User)
(Manager 1)
(Manager 2)
eid 101
:auth/clearance
:mgt/employees
EntityConsumer(e)
‣ add(employee)
Entity consumers
Molecule
EmployeeAdministration(eid)
‣ add(employee)
Authorization(eid)
‣ authorize(employee)
PasswChange(eid)
‣ setNew(passw)
Atomic Attributes
eid 101
:person/name
:user/email
:user/passw
:person/id
:person/born
:person/name
:user/email
:user/passw
:site/status
:auth/clearance
:mgt/employees
:mgt/employees
eid 101
:auth/clearance
(User)
(Manager 1)
(Manager 2)eid 101
:auth/clearance
:mgt/employees
Entity id consumers - with molecular entities
Molecule
EmployeeAdministration(eid)
‣ add(employee)
Authorization(eid)
‣ authorize(employee)
:person/id
:person/born
:person/name
:user/email
:user/passw
:site/status
:auth/clearance
:mgt/employees
:mgt/employees
eid 101
:auth/clearance (Manager 1)
(Manager 2)eid 101
:auth/clearance
:mgt/employees
no
domain
classes!?
PasswChange(eid)
‣ setNew(passw)
eid 101
:person/name
:user/email
:user/passw
(User)
Atomic Attributes Entity id consumers - with molecular entities
Molecule
Molecular entities
PasswChange(eid, newPassw)
‣ setNew(passw)
eid 101
:person/name
:user/email
:user/passw
(User)
Molecule
PasswChange(eid, newPassw)
Get current User data:
Check stuff...
Save:
Molecules
Molecule
Molecules• Get data from the app process
• No need to cast raw data from
a db server to populate rigid
domain classes, only to pull the
data out again
• Get/set exactly the data you
need
• Always typed data
• Easy type-safe migrations
• Use your domain terms directly
• Absolute minium of ceremony
• Maximum runtime performance
• Time
• Fun!
PasswChange(eid, newPassw)
Get current User data:
Check stuff...
Save:
Molecule
• Get data from the app process
• No need to cast raw data from
a db server to populate rigid
domain classes, only to pull it out
again
• Get/set exactly the data you
need
• Always typed data
• Easy type-safe migrations
• Use your domain terms directly
• Absolute minium of ceremony
• Maximum runtime performance
• Time
• Fun!
Thank you!
Questions?
Molecule
4
github.com/scalamolecule/molecule
scalamolecule.org
datomic.com
Marc Grue
April 2017

Mais conteúdo relacionado

Último

Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...masabamasaba
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile EnvironmentVictorSzoltysek
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Hararemasabamasaba
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 

Último (20)

Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 

Destaque

PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...DevGAMM Conference
 
Barbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationBarbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationErica Santiago
 

Destaque (20)

PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
 
Barbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationBarbie - Brand Strategy Presentation
Barbie - Brand Strategy Presentation
 

Molecule Scala meta-DSL for Datomic