SlideShare a Scribd company logo
internal DSLs
                        Zef Hemel




Tuesday, May 18, 2010
Internal DSLs are particular ways of
                 using a host language to give the host
                 language the feel of a particular
                 language.


                                             Martin Fowler




Tuesday, May 18, 2010
Internal DSLs are particular ways of
          abusing a host language to give the host
            language the feel of a particular
            language.


                                        Martin Fowler




Tuesday, May 18, 2010
fluent interfaces

                        flexible syntax

                        method missing

                          reflection

                            macros


Tuesday, May 18, 2010
Tuesday, May 18, 2010
fluent interfaces



Tuesday, May 18, 2010
Order o = new Order();
                        Product p1 = new Product(1,Product.find(“Billy”));
                        o.addProduct(p1);
                        Product p2 = new Product(2,Product.find(”Janso"));
                        o.addProduct(p2);
                        Product p3 = new Product(4,Product.find(“Traby"));
                        o.addProduct(p3);
                        o.setPriorityRush(true);
                        customer.addOrder(o);




                                                   http://www.st.ewi.tudelft.nl/~bouwers/main/slides/2008jspring.pdf

Tuesday, May 18, 2010
customer.newOrder()
                                .with(1, "Billy")
                                .with(2, "Janso")
                                .with(4, "Traby")
                                .priorityRush()
                                .done();




Tuesday, May 18, 2010
public class Customer {
                           ...
                           public OrderBuilder newOrder() {
                             return new OrderBuilder(this);
                           }
                        }




Tuesday, May 18, 2010
public class OrderBuilder {
                          // ...

                            public OrderBuilder(Customer customer) {
                              this.customer = customer;
                              this.order = new Order();
                            }

                            public OrderBuilder with(int id, String name) {
                               order.addProduct(new Product(id, name));
                               return this;
                            }

                            public OrderBuilder priorityRush() {
                              order.setPriorityRush(true);
                              return this;
                            }

                            public void done() {
                              customer.addOrder(this.order);
                            }
                        }

Tuesday, May 18, 2010
public class OrderBuilder {
                          // ...

                            public OrderBuilder(Customer customer) {
                              this.customer = customer;
                              this.order = new Order();
                            }

                            public OrderBuilder with(int id, String name) {
                               order.addProduct(new Product(id, name));
                               return this;
                            }

                            public OrderBuilder priorityRush() {
                              order.setPriorityRush(true);
                              return this;
                            }

                            public void done() {
                              customer.addOrder(this.order);
                            }
                        }

Tuesday, May 18, 2010
flexible syntax



Tuesday, May 18, 2010
header("Add entry")
      form {
        table {
          row {
             col { text("Your name:") }
             col { newEntry.name = input(newEntry.name) }
          }
          row {
             col { text("Your message:") }
             col { newEntry.text = inputText(newEntry.text) }
          }
        }
        button("Post") {
          newEntry.save()
          goto(Home())
        }
      }




Tuesday, May 18, 2010
in Scala




Tuesday, May 18, 2010
case class Home() extends Page {
                def ui {
                  header("Welcome to my guestbook!")
                  section {
                    header("All entries")
                    list {
                      for (e <- cache("entries", Entry.all)) {
                         listitem {
                           form {
                             text(e.name)
                             text(": ")
                             text(e.text)
                             button("Delete") {
                               e.delete()
                               goto(Home())
                             }
                           }
                         }
                      }
                    }
                  }
                }
              }



Tuesday, May 18, 2010
case class Home() extends Page {
                def ui {
                  header("Welcome to my guestbook!")
                  section {
                    entries
                  }
                }

                  def entries {
                    header("All entries")
                    list {
                      for (e <- cache("entries", Entry.all)) {
                        listitem {
                           form {
                             text(e.name)
                             text(": ")
                             text(e.text)
                             button("Delete") {
                               e.delete()
                               goto(Home())
                             }
                           }
                        }
                      }
                    }
                  }
              }

Tuesday, May 18, 2010
object DefaultStyle extends Style {
                block("headerblock") >> header {
                  fontsize = 30 pt;
                  width = 100 percent;
                  bgcolor = "#eeeeee";
                }
                section >> header {
                  color = "#0c0ccc";
                }
                body {
                  fontfamily = "Helvetica, Arial, Verdana, sans-serif"
                }
              }




Tuesday, May 18, 2010
object DefaultStyle extends Style {
                block("headerblock").>>(header {
                   fontsize = 30 pt;
                   width = 100 percent;
                   bgcolor = "#eeeeee";
                })
                section.>>(header {
                   color = "#0c0ccc";
                })
                body {
                   fontfamily = "Helvetica, Arial, Verdana, sans-serif"
                }
              }




Tuesday, May 18, 2010
object DefaultStyle extends Style {
                block("headerblock").>>(header(() => {
                   fontsize = 30 pt;
                   width = 100 percent;
                   bgcolor = "#eeeeee";
                }))
                section.>>(header(() => {
                   color = "#0c0ccc";
                }))
                body(() => {
                   fontfamily = "Helvetica, Arial, Verdana, sans-serif"
                })
              }




Tuesday, May 18, 2010
a >> b == a.>>(b)




Tuesday, May 18, 2010
section {
                          header("All entries")
                          ...
                        }




Tuesday, May 18, 2010
section(() => {
                           header("All entries")
                           ...
                        })




Tuesday, May 18, 2010
section(() => {
                           header("All entries")
                           ...
                        })




                 def section(content : => Unit) {
                   write("<div class='section'>")
                   content
                   write("</div>")
                 }


Tuesday, May 18, 2010
ruby



Tuesday, May 18, 2010
create_table :posts do |t|
                          t.string :name
                          t.string :title
                          t.text   :content
                        end




Tuesday, May 18, 2010
create_table(:posts,do |t|
                          t.string(:name)
                          t.string(:title)
                          t.text (:content)
                        end)




Tuesday, May 18, 2010
class Post < ActiveRecord::Base
                          validates_presence_of :name, :title
                          validates_length_of :title, :minimum => 5
                        end




Tuesday, May 18, 2010
class Post < ActiveRecord::Base
                          validates_presence_of(:name, :title)
                          validates_length_of(:title, :minimum => 5)
                        end




Tuesday, May 18, 2010
method missing



Tuesday, May 18, 2010
scala



Tuesday, May 18, 2010
width = 100 percent;




Tuesday, May 18, 2010
width = 100 percent;




             def width_=(w: UnitInt) {
               ...
             }




Tuesday, May 18, 2010
width_=(100 percent);




Tuesday, May 18, 2010
width_=(100.percent);




Tuesday, May 18, 2010
width_=(100.percent());




Tuesday, May 18, 2010
implicit def int2UnitInt(i: Int) =
                              new UnitIntWrapper(i)




Tuesday, May 18, 2010
width_=(100.percent());




Tuesday, May 18, 2010
width_=(int2UnitInt(100).percent());




Tuesday, May 18, 2010
class UnitIntWrapper(i: Int) {
  ...

      def percent = new PercentUnitInt(i)

      class PercentUnitInt(i: Int) extends UnitInt {
        override def toString = i + "%"
      }
}




Tuesday, May 18, 2010
ruby



Tuesday, May 18, 2010
Person.find_by_name('Zef')




Tuesday, May 18, 2010
class Person
           def self.find(key, value)
             puts "You want results from #{key} with a value of #{value}"
           end
         end

         Person.find('name', 'Zef')




Tuesday, May 18, 2010
class Person
         def self.find(key, value)
           puts "You want results from #{key} with a value of #{value}"
         end

         def self.method_missing(id, *args)
           if id.id2name =~ /find_by_(.+)/
             return self.find(Regexp.last_match(1),   args[0])
           else
             raise NoMethodError
           end
         end
       end

       Person.find_by_name('Zef')




Tuesday, May 18, 2010
reflection



Tuesday, May 18, 2010
public class Person {
                           @Persistent
                           public String name;
                           @Persistent
                           public int age;
                        }




Tuesday, May 18, 2010
void persist(Object obj) {
        Class cls = obj.getClass();
        Field[] fields = cls.getFields();
        for(Field f : fields) {
          Persistent anno = f.getAnnotation(Persistent.class);
          if(anno != null) {
            System.out.println(f.getName());
          }
        }
      }




Tuesday, May 18, 2010
macros



Tuesday, May 18, 2010
int one() {
              printf("One!");
              return 1;
           }

           int two() {
              printf("Two!");
              return 2;
           }

           ...

           int c = choice(n == 1, one(), two());



Tuesday, May 18, 2010
int choice(BOOL c, int ifTrue, int ifFalse) {
        return c ? ifTrue : ifFalse;
     }




Tuesday, May 18, 2010
int one() {
              printf("One!");
              return 1;
           }

           int two() {
              printf("Two!");
              return 2;
           }

           ...

           int c = choice(n == 1, one(), two());



Tuesday, May 18, 2010
#define CHOICE(c,ifTrue,ifFalse) 
                            (c) ? (ifTrue) : (ifFalse)




Tuesday, May 18, 2010
#define CHOICE(c,ifTrue,ifFalse) 
                                (c) ? (ifTrue) : (ifFalse)




                        int c = CHOICE(n == 1, one(), two());




Tuesday, May 18, 2010
#define CHOICE(c,ifTrue,ifFalse) 
                                (c) ? (ifTrue) : (ifFalse)




                        int c = CHOICE(n == 1, one(), two());



                        int c = (n == 1) ? (one()) : (two());




Tuesday, May 18, 2010
clojure (a Lisp)




Tuesday, May 18, 2010
homoiconic
                         code is data
                         data is code




Tuesday, May 18, 2010
(+ 1 2 3)




Tuesday, May 18, 2010
(+ 1 2 3)   =6




Tuesday, May 18, 2010
'(+ 1 2 3)




Tuesday, May 18, 2010
(first '(+ 1 2 3))




Tuesday, May 18, 2010
(first '(+ 1 2 3))   =+




Tuesday, May 18, 2010
(cons '+ (reverse (rest '(+ 1 2 3))))




Tuesday, May 18, 2010
(cons '+ (reverse (rest '(+ 1 2 3))))

                        = (+ 3 2 1)




Tuesday, May 18, 2010
(eval
 (cons '+ (reverse (rest '(+ 1 2 3)))))




Tuesday, May 18, 2010
(eval
 (cons '+ (reverse (rest '(+ 1 2 3)))))

                        =6




Tuesday, May 18, 2010
(if (= n 10)
                           (print "It was ten!”)
                           nil)




Tuesday, May 18, 2010
(when (= n 10)
                           (print "It was ten!”))




Tuesday, May 18, 2010
(defn when [c ifTrue]
                   (if c
                     ifTrue
                     nil))




Tuesday, May 18, 2010
(when (= n 10)
                           (print "It was ten!”))




Tuesday, May 18, 2010
(defmacro when [c ifTrue]
                   (list 'if c ifTrue 'nil))




Tuesday, May 18, 2010
(defmacro when [c ifTrue]
                   `(if ~c
                     ~ifTrue
                     nil))




Tuesday, May 18, 2010
(when (= n 10)
                           (print "It was ten!”))




                        (if (= n 10)
                           (print "It was ten!”)
                           nil)




Tuesday, May 18, 2010
(when (= n 10)
                           (print "It was ten!”))




                        (if (= n 10)
                           (print "It was ten!”)
                           nil)




Tuesday, May 18, 2010
(loop for i in *random*
                           counting (evenp i) into evens
                           counting (oddp i) into odds
                           summing i into total
                           maximizing i into max
                           minimizing i into min
                           finally (return (list min max total evens odds)))




Tuesday, May 18, 2010
(defent User
               [:username   :string {:unique true}]
               [:openid     :string]
               [:email      :email]
               [:points     :int])




                                        http://github.com/zefhemel/adia

Tuesday, May 18, 2010
(defwebfn show [u User]
                  [:h1 "Posted items"]
                  [:ul
                   (for [i (query Item
                             :where {:author (:_id u)}
                             :order-by {:date -1})]
                     [:li (:title i)])])




Tuesday, May 18, 2010
advantages



Tuesday, May 18, 2010
easy to develop

                        builds on existing platform

                           existing community




Tuesday, May 18, 2010
disadvantages



Tuesday, May 18, 2010
<h1>Hello, Rails!</h1>
                        <%= link_to "My Blog", post_path %>




                                                     http://zef.me/2308/when-rails-fails

Tuesday, May 18, 2010
<h1>Hello, Rails!</h1>
                                  <%= link_to "My Blog", post_path %>




               post_url failed to generate from
               {:controller=>"posts", :action=>"show"} – you may have ambiguous
               routes, or you may need to supply additional parameters for this
               route.  content_url has the following required parameters:
               ["posts", :id] – are they all satisfied?


                                                               http://zef.me/2308/when-rails-fails

Tuesday, May 18, 2010
<%= link_to 'Destroy', post, :confrm => 'Are you sure?', :method => :delete %> 




Tuesday, May 18, 2010
<%= link_to 'Destroy', post, :confrm => 'Are you sure?', :method => :delete %> 




Tuesday, May 18, 2010
class Post < ActiveRecord::Base
                          validates_presence_of :nam
                        end




Tuesday, May 18, 2010
class Post < ActiveRecord::Base
                          validates_presence_of :nam
                        end




Tuesday, May 18, 2010
no static checking




                        late discovery of errors




Tuesday, May 18, 2010
no static checking




                        late discovery of errors




Tuesday, May 18, 2010
Tuesday, May 18, 2010
Tuesday, May 18, 2010
non-domain specific error messages




Tuesday, May 18, 2010
Tuesday, May 18, 2010
errors hard to trace back to origin




Tuesday, May 18, 2010
Table         t = table("table").as("t");
     Table         t1 = table("table1").as("t1");
     Field         tId = t.field("id");
     Field         t1Id = t1.field("id");
     Field         t1Time = t1.field("time");

     Sql sql = select(tId).from(t).join(inner(t1, tId.eq(t1Id)))
       .where(and(tId.eq("'a'"), t1Time.between("'1900'", "'2000'")))
        .groupBy(tId).having(tId.gt("1"))
        .orderBy(asc(tId));




                                                       http://www.jequel.de

Tuesday, May 18, 2010
limited freedom in syntax




Tuesday, May 18, 2010
+                      -
                        quick development    lack of static checking

                         built on existing    errors hard to trace
                             platform            back to origin

                    existing community        bad error messages

                                              limited freedom in
                                                    syntax


Tuesday, May 18, 2010
Tuesday, May 18, 2010
                        ?

More Related Content

What's hot

The Ring programming language version 1.5.2 book - Part 45 of 181
The Ring programming language version 1.5.2 book - Part 45 of 181The Ring programming language version 1.5.2 book - Part 45 of 181
The Ring programming language version 1.5.2 book - Part 45 of 181
Mahmoud Samir Fayed
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
André Faria Gomes
 
Design Patterns in Go Code
Design Patterns in Go CodeDesign Patterns in Go Code
Design Patterns in Go Code
Kamil Mówiński
 
Groovy kind of test
Groovy kind of testGroovy kind of test
Groovy kind of test
Torsten Mandry
 
Marimba - Ein MapReduce-basiertes Programmiermodell für selbstwartbare Aggreg...
Marimba - Ein MapReduce-basiertes Programmiermodell für selbstwartbare Aggreg...Marimba - Ein MapReduce-basiertes Programmiermodell für selbstwartbare Aggreg...
Marimba - Ein MapReduce-basiertes Programmiermodell für selbstwartbare Aggreg...
Johannes Schildgen
 
The love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with XamarinThe love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with Xamarin
Lorenz Cuno Klopfenstein
 
mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecturezefhemel
 
The Ring programming language version 1.10 book - Part 56 of 212
The Ring programming language version 1.10 book - Part 56 of 212The Ring programming language version 1.10 book - Part 56 of 212
The Ring programming language version 1.10 book - Part 56 of 212
Mahmoud Samir Fayed
 
Reading the .explain() Output
Reading the .explain() OutputReading the .explain() Output
Reading the .explain() Output
MongoDB
 
Pytables
PytablesPytables
Pytables
rocketcircus
 
Ditec esoft C# project
Ditec esoft C# projectDitec esoft C# project
Ditec esoft C# project
K.K.T Madhusanka
 
Ditec esoft C# project
Ditec esoft C# project Ditec esoft C# project
Ditec esoft C# project
K.K.T Madhusanka
 

What's hot (14)

The Ring programming language version 1.5.2 book - Part 45 of 181
The Ring programming language version 1.5.2 book - Part 45 of 181The Ring programming language version 1.5.2 book - Part 45 of 181
The Ring programming language version 1.5.2 book - Part 45 of 181
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
Design Patterns in Go Code
Design Patterns in Go CodeDesign Patterns in Go Code
Design Patterns in Go Code
 
H base development
H base developmentH base development
H base development
 
Groovy kind of test
Groovy kind of testGroovy kind of test
Groovy kind of test
 
Marimba - Ein MapReduce-basiertes Programmiermodell für selbstwartbare Aggreg...
Marimba - Ein MapReduce-basiertes Programmiermodell für selbstwartbare Aggreg...Marimba - Ein MapReduce-basiertes Programmiermodell für selbstwartbare Aggreg...
Marimba - Ein MapReduce-basiertes Programmiermodell für selbstwartbare Aggreg...
 
The love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with XamarinThe love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with Xamarin
 
mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecture
 
The Ring programming language version 1.10 book - Part 56 of 212
The Ring programming language version 1.10 book - Part 56 of 212The Ring programming language version 1.10 book - Part 56 of 212
The Ring programming language version 1.10 book - Part 56 of 212
 
Reading the .explain() Output
Reading the .explain() OutputReading the .explain() Output
Reading the .explain() Output
 
Pytables
PytablesPytables
Pytables
 
Vb file
Vb fileVb file
Vb file
 
Ditec esoft C# project
Ditec esoft C# projectDitec esoft C# project
Ditec esoft C# project
 
Ditec esoft C# project
Ditec esoft C# project Ditec esoft C# project
Ditec esoft C# project
 

Similar to Internal DSLs

Internal DSLs Scala
Internal DSLs ScalaInternal DSLs Scala
Internal DSLs Scala
zefhemel
 
Create a class BinarySearchTree- A class that implements the ADT binar.pdf
Create a class BinarySearchTree- A class that implements the ADT binar.pdfCreate a class BinarySearchTree- A class that implements the ADT binar.pdf
Create a class BinarySearchTree- A class that implements the ADT binar.pdf
shyamsunder1211
 
Wicket KT part 2
Wicket KT part 2Wicket KT part 2
Wicket KT part 2
stuq
 
20160616技術會議
20160616技術會議20160616技術會議
20160616技術會議
Jason Kuan
 
知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips
ikeyat
 
VB 6
VB 6VB 6
JDD2015: Where Test Doubles can lead you... - Sebastian Malaca
JDD2015: Where Test Doubles can lead you...  - Sebastian Malaca JDD2015: Where Test Doubles can lead you...  - Sebastian Malaca
JDD2015: Where Test Doubles can lead you... - Sebastian Malaca
PROIDEA
 
Creating a Facebook Clone - Part XVI.pdf
Creating a Facebook Clone - Part XVI.pdfCreating a Facebook Clone - Part XVI.pdf
Creating a Facebook Clone - Part XVI.pdf
ShaiAlmog1
 
This is a java lab assignment. I have added the first part java re.pdf
This is a java lab assignment. I have added the first part java re.pdfThis is a java lab assignment. I have added the first part java re.pdf
This is a java lab assignment. I have added the first part java re.pdf
feetshoemart
 
C# Starter L04-Collections
C# Starter L04-CollectionsC# Starter L04-Collections
C# Starter L04-CollectionsMohammad Shaker
 
Combatendo code smells em Java
Combatendo code smells em Java Combatendo code smells em Java
Combatendo code smells em Java
Emmanuel Neri
 
File Handling Program
File Handling ProgramFile Handling Program
Database handling with room
Database handling with roomDatabase handling with room
Database handling with room
Sergi Martínez
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java
DEVTYPE
 
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum Ukraine
 
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
tdc-globalcode
 
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
.NET Conf UY
 
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docxlab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
DIPESH30
 
H base programming
H base programmingH base programming
H base programming
Muthusamy Manigandan
 

Similar to Internal DSLs (20)

Internal DSLs Scala
Internal DSLs ScalaInternal DSLs Scala
Internal DSLs Scala
 
Awt
AwtAwt
Awt
 
Create a class BinarySearchTree- A class that implements the ADT binar.pdf
Create a class BinarySearchTree- A class that implements the ADT binar.pdfCreate a class BinarySearchTree- A class that implements the ADT binar.pdf
Create a class BinarySearchTree- A class that implements the ADT binar.pdf
 
Wicket KT part 2
Wicket KT part 2Wicket KT part 2
Wicket KT part 2
 
20160616技術會議
20160616技術會議20160616技術會議
20160616技術會議
 
知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips
 
VB 6
VB 6VB 6
VB 6
 
JDD2015: Where Test Doubles can lead you... - Sebastian Malaca
JDD2015: Where Test Doubles can lead you...  - Sebastian Malaca JDD2015: Where Test Doubles can lead you...  - Sebastian Malaca
JDD2015: Where Test Doubles can lead you... - Sebastian Malaca
 
Creating a Facebook Clone - Part XVI.pdf
Creating a Facebook Clone - Part XVI.pdfCreating a Facebook Clone - Part XVI.pdf
Creating a Facebook Clone - Part XVI.pdf
 
This is a java lab assignment. I have added the first part java re.pdf
This is a java lab assignment. I have added the first part java re.pdfThis is a java lab assignment. I have added the first part java re.pdf
This is a java lab assignment. I have added the first part java re.pdf
 
C# Starter L04-Collections
C# Starter L04-CollectionsC# Starter L04-Collections
C# Starter L04-Collections
 
Combatendo code smells em Java
Combatendo code smells em Java Combatendo code smells em Java
Combatendo code smells em Java
 
File Handling Program
File Handling ProgramFile Handling Program
File Handling Program
 
Database handling with room
Database handling with roomDatabase handling with room
Database handling with room
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java
 
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
 
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
 
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
 
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docxlab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
 
H base programming
H base programmingH base programming
H base programming
 

More from zefhemel

Docker ecosystem
Docker ecosystemDocker ecosystem
Docker ecosystem
zefhemel
 
Expand your horizons
Expand your horizonsExpand your horizons
Expand your horizons
zefhemel
 
Avoiding JavaScript Pitfalls Through Tree Hugging
Avoiding JavaScript Pitfalls Through Tree HuggingAvoiding JavaScript Pitfalls Through Tree Hugging
Avoiding JavaScript Pitfalls Through Tree Hugging
zefhemel
 
Cloud9 IDE Talk at meet.js Poznań
Cloud9 IDE Talk at meet.js PoznańCloud9 IDE Talk at meet.js Poznań
Cloud9 IDE Talk at meet.js Poznań
zefhemel
 
Frontrow conf
Frontrow confFrontrow conf
Frontrow confzefhemel
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomerzefhemel
 
mobl
moblmobl
mobl
zefhemel
 
PIL - A Platform Independent Language
PIL - A Platform Independent LanguagePIL - A Platform Independent Language
PIL - A Platform Independent Language
zefhemel
 
WebWorkFlow
WebWorkFlowWebWorkFlow
WebWorkFlow
zefhemel
 
Abstractie (Dutch)
Abstractie (Dutch)Abstractie (Dutch)
Abstractie (Dutch)
zefhemel
 
WebDSL
WebDSLWebDSL
WebDSL
zefhemel
 

More from zefhemel (11)

Docker ecosystem
Docker ecosystemDocker ecosystem
Docker ecosystem
 
Expand your horizons
Expand your horizonsExpand your horizons
Expand your horizons
 
Avoiding JavaScript Pitfalls Through Tree Hugging
Avoiding JavaScript Pitfalls Through Tree HuggingAvoiding JavaScript Pitfalls Through Tree Hugging
Avoiding JavaScript Pitfalls Through Tree Hugging
 
Cloud9 IDE Talk at meet.js Poznań
Cloud9 IDE Talk at meet.js PoznańCloud9 IDE Talk at meet.js Poznań
Cloud9 IDE Talk at meet.js Poznań
 
Frontrow conf
Frontrow confFrontrow conf
Frontrow conf
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomer
 
mobl
moblmobl
mobl
 
PIL - A Platform Independent Language
PIL - A Platform Independent LanguagePIL - A Platform Independent Language
PIL - A Platform Independent Language
 
WebWorkFlow
WebWorkFlowWebWorkFlow
WebWorkFlow
 
Abstractie (Dutch)
Abstractie (Dutch)Abstractie (Dutch)
Abstractie (Dutch)
 
WebDSL
WebDSLWebDSL
WebDSL
 

Recently uploaded

To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 

Recently uploaded (20)

To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 

Internal DSLs

  • 1. internal DSLs Zef Hemel Tuesday, May 18, 2010
  • 2. Internal DSLs are particular ways of using a host language to give the host language the feel of a particular language. Martin Fowler Tuesday, May 18, 2010
  • 3. Internal DSLs are particular ways of abusing a host language to give the host language the feel of a particular language. Martin Fowler Tuesday, May 18, 2010
  • 4. fluent interfaces flexible syntax method missing reflection macros Tuesday, May 18, 2010
  • 7. Order o = new Order(); Product p1 = new Product(1,Product.find(“Billy”)); o.addProduct(p1); Product p2 = new Product(2,Product.find(”Janso")); o.addProduct(p2); Product p3 = new Product(4,Product.find(“Traby")); o.addProduct(p3); o.setPriorityRush(true); customer.addOrder(o); http://www.st.ewi.tudelft.nl/~bouwers/main/slides/2008jspring.pdf Tuesday, May 18, 2010
  • 8. customer.newOrder() .with(1, "Billy") .with(2, "Janso") .with(4, "Traby") .priorityRush() .done(); Tuesday, May 18, 2010
  • 9. public class Customer { ... public OrderBuilder newOrder() { return new OrderBuilder(this); } } Tuesday, May 18, 2010
  • 10. public class OrderBuilder { // ... public OrderBuilder(Customer customer) { this.customer = customer; this.order = new Order(); } public OrderBuilder with(int id, String name) { order.addProduct(new Product(id, name)); return this; } public OrderBuilder priorityRush() { order.setPriorityRush(true); return this; } public void done() { customer.addOrder(this.order); } } Tuesday, May 18, 2010
  • 11. public class OrderBuilder { // ... public OrderBuilder(Customer customer) { this.customer = customer; this.order = new Order(); } public OrderBuilder with(int id, String name) { order.addProduct(new Product(id, name)); return this; } public OrderBuilder priorityRush() { order.setPriorityRush(true); return this; } public void done() { customer.addOrder(this.order); } } Tuesday, May 18, 2010
  • 13. header("Add entry") form { table { row { col { text("Your name:") } col { newEntry.name = input(newEntry.name) } } row { col { text("Your message:") } col { newEntry.text = inputText(newEntry.text) } } } button("Post") { newEntry.save() goto(Home()) } } Tuesday, May 18, 2010
  • 15. case class Home() extends Page { def ui { header("Welcome to my guestbook!") section { header("All entries") list { for (e <- cache("entries", Entry.all)) { listitem { form { text(e.name) text(": ") text(e.text) button("Delete") { e.delete() goto(Home()) } } } } } } } } Tuesday, May 18, 2010
  • 16. case class Home() extends Page { def ui { header("Welcome to my guestbook!") section { entries } } def entries { header("All entries") list { for (e <- cache("entries", Entry.all)) { listitem { form { text(e.name) text(": ") text(e.text) button("Delete") { e.delete() goto(Home()) } } } } } } } Tuesday, May 18, 2010
  • 17. object DefaultStyle extends Style { block("headerblock") >> header { fontsize = 30 pt; width = 100 percent; bgcolor = "#eeeeee"; } section >> header { color = "#0c0ccc"; } body { fontfamily = "Helvetica, Arial, Verdana, sans-serif" } } Tuesday, May 18, 2010
  • 18. object DefaultStyle extends Style { block("headerblock").>>(header { fontsize = 30 pt; width = 100 percent; bgcolor = "#eeeeee"; }) section.>>(header { color = "#0c0ccc"; }) body { fontfamily = "Helvetica, Arial, Verdana, sans-serif" } } Tuesday, May 18, 2010
  • 19. object DefaultStyle extends Style { block("headerblock").>>(header(() => { fontsize = 30 pt; width = 100 percent; bgcolor = "#eeeeee"; })) section.>>(header(() => { color = "#0c0ccc"; })) body(() => { fontfamily = "Helvetica, Arial, Verdana, sans-serif" }) } Tuesday, May 18, 2010
  • 20. a >> b == a.>>(b) Tuesday, May 18, 2010
  • 21. section { header("All entries") ... } Tuesday, May 18, 2010
  • 22. section(() => { header("All entries") ... }) Tuesday, May 18, 2010
  • 23. section(() => { header("All entries") ... }) def section(content : => Unit) { write("<div class='section'>") content write("</div>") } Tuesday, May 18, 2010
  • 25. create_table :posts do |t| t.string :name t.string :title t.text :content end Tuesday, May 18, 2010
  • 26. create_table(:posts,do |t| t.string(:name) t.string(:title) t.text (:content) end) Tuesday, May 18, 2010
  • 27. class Post < ActiveRecord::Base validates_presence_of :name, :title validates_length_of :title, :minimum => 5 end Tuesday, May 18, 2010
  • 28. class Post < ActiveRecord::Base validates_presence_of(:name, :title) validates_length_of(:title, :minimum => 5) end Tuesday, May 18, 2010
  • 31. width = 100 percent; Tuesday, May 18, 2010
  • 32. width = 100 percent; def width_=(w: UnitInt) { ... } Tuesday, May 18, 2010
  • 36. implicit def int2UnitInt(i: Int) = new UnitIntWrapper(i) Tuesday, May 18, 2010
  • 39. class UnitIntWrapper(i: Int) { ... def percent = new PercentUnitInt(i) class PercentUnitInt(i: Int) extends UnitInt { override def toString = i + "%" } } Tuesday, May 18, 2010
  • 42. class Person def self.find(key, value) puts "You want results from #{key} with a value of #{value}" end end Person.find('name', 'Zef') Tuesday, May 18, 2010
  • 43. class Person def self.find(key, value) puts "You want results from #{key} with a value of #{value}" end def self.method_missing(id, *args) if id.id2name =~ /find_by_(.+)/ return self.find(Regexp.last_match(1), args[0]) else raise NoMethodError end end end Person.find_by_name('Zef') Tuesday, May 18, 2010
  • 45. public class Person { @Persistent public String name; @Persistent public int age; } Tuesday, May 18, 2010
  • 46. void persist(Object obj) { Class cls = obj.getClass(); Field[] fields = cls.getFields(); for(Field f : fields) { Persistent anno = f.getAnnotation(Persistent.class); if(anno != null) { System.out.println(f.getName()); } } } Tuesday, May 18, 2010
  • 48. int one() { printf("One!"); return 1; } int two() { printf("Two!"); return 2; } ... int c = choice(n == 1, one(), two()); Tuesday, May 18, 2010
  • 49. int choice(BOOL c, int ifTrue, int ifFalse) { return c ? ifTrue : ifFalse; } Tuesday, May 18, 2010
  • 50. int one() { printf("One!"); return 1; } int two() { printf("Two!"); return 2; } ... int c = choice(n == 1, one(), two()); Tuesday, May 18, 2010
  • 51. #define CHOICE(c,ifTrue,ifFalse) (c) ? (ifTrue) : (ifFalse) Tuesday, May 18, 2010
  • 52. #define CHOICE(c,ifTrue,ifFalse) (c) ? (ifTrue) : (ifFalse) int c = CHOICE(n == 1, one(), two()); Tuesday, May 18, 2010
  • 53. #define CHOICE(c,ifTrue,ifFalse) (c) ? (ifTrue) : (ifFalse) int c = CHOICE(n == 1, one(), two()); int c = (n == 1) ? (one()) : (two()); Tuesday, May 18, 2010
  • 55. homoiconic code is data data is code Tuesday, May 18, 2010
  • 56. (+ 1 2 3) Tuesday, May 18, 2010
  • 57. (+ 1 2 3) =6 Tuesday, May 18, 2010
  • 58. '(+ 1 2 3) Tuesday, May 18, 2010
  • 59. (first '(+ 1 2 3)) Tuesday, May 18, 2010
  • 60. (first '(+ 1 2 3)) =+ Tuesday, May 18, 2010
  • 61. (cons '+ (reverse (rest '(+ 1 2 3)))) Tuesday, May 18, 2010
  • 62. (cons '+ (reverse (rest '(+ 1 2 3)))) = (+ 3 2 1) Tuesday, May 18, 2010
  • 63. (eval (cons '+ (reverse (rest '(+ 1 2 3))))) Tuesday, May 18, 2010
  • 64. (eval (cons '+ (reverse (rest '(+ 1 2 3))))) =6 Tuesday, May 18, 2010
  • 65. (if (= n 10) (print "It was ten!”) nil) Tuesday, May 18, 2010
  • 66. (when (= n 10) (print "It was ten!”)) Tuesday, May 18, 2010
  • 67. (defn when [c ifTrue] (if c ifTrue nil)) Tuesday, May 18, 2010
  • 68. (when (= n 10) (print "It was ten!”)) Tuesday, May 18, 2010
  • 69. (defmacro when [c ifTrue] (list 'if c ifTrue 'nil)) Tuesday, May 18, 2010
  • 70. (defmacro when [c ifTrue] `(if ~c ~ifTrue nil)) Tuesday, May 18, 2010
  • 71. (when (= n 10) (print "It was ten!”)) (if (= n 10) (print "It was ten!”) nil) Tuesday, May 18, 2010
  • 72. (when (= n 10) (print "It was ten!”)) (if (= n 10) (print "It was ten!”) nil) Tuesday, May 18, 2010
  • 73. (loop for i in *random* counting (evenp i) into evens counting (oddp i) into odds summing i into total maximizing i into max minimizing i into min finally (return (list min max total evens odds))) Tuesday, May 18, 2010
  • 74. (defent User [:username :string {:unique true}] [:openid :string] [:email :email] [:points :int]) http://github.com/zefhemel/adia Tuesday, May 18, 2010
  • 75. (defwebfn show [u User] [:h1 "Posted items"] [:ul (for [i (query Item :where {:author (:_id u)} :order-by {:date -1})] [:li (:title i)])]) Tuesday, May 18, 2010
  • 77. easy to develop builds on existing platform existing community Tuesday, May 18, 2010
  • 79. <h1>Hello, Rails!</h1> <%= link_to "My Blog", post_path %> http://zef.me/2308/when-rails-fails Tuesday, May 18, 2010
  • 80. <h1>Hello, Rails!</h1> <%= link_to "My Blog", post_path %> post_url failed to generate from {:controller=>"posts", :action=>"show"} – you may have ambiguous routes, or you may need to supply additional parameters for this route.  content_url has the following required parameters: ["posts", :id] – are they all satisfied? http://zef.me/2308/when-rails-fails Tuesday, May 18, 2010
  • 81. <%= link_to 'Destroy', post, :confrm => 'Are you sure?', :method => :delete %>  Tuesday, May 18, 2010
  • 82. <%= link_to 'Destroy', post, :confrm => 'Are you sure?', :method => :delete %>  Tuesday, May 18, 2010
  • 83. class Post < ActiveRecord::Base   validates_presence_of :nam end Tuesday, May 18, 2010
  • 84. class Post < ActiveRecord::Base   validates_presence_of :nam end Tuesday, May 18, 2010
  • 85. no static checking late discovery of errors Tuesday, May 18, 2010
  • 86. no static checking late discovery of errors Tuesday, May 18, 2010
  • 89. non-domain specific error messages Tuesday, May 18, 2010
  • 91. errors hard to trace back to origin Tuesday, May 18, 2010
  • 92. Table t = table("table").as("t"); Table t1 = table("table1").as("t1"); Field tId = t.field("id"); Field t1Id = t1.field("id"); Field t1Time = t1.field("time"); Sql sql = select(tId).from(t).join(inner(t1, tId.eq(t1Id)))   .where(and(tId.eq("'a'"), t1Time.between("'1900'", "'2000'")))    .groupBy(tId).having(tId.gt("1"))    .orderBy(asc(tId)); http://www.jequel.de Tuesday, May 18, 2010
  • 93. limited freedom in syntax Tuesday, May 18, 2010
  • 94. + - quick development lack of static checking built on existing errors hard to trace platform back to origin existing community bad error messages limited freedom in syntax Tuesday, May 18, 2010