SlideShare une entreprise Scribd logo
1  sur  95
Télécharger pour lire hors ligne
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
                        ?

Contenu connexe

Tendances

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 181Mahmoud Samir Fayed
 
Design Patterns in Go Code
Design Patterns in Go CodeDesign Patterns in Go Code
Design Patterns in Go CodeKamil Mówiński
 
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 XamarinLorenz 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 212Mahmoud Samir Fayed
 
Reading the .explain() Output
Reading the .explain() OutputReading the .explain() Output
Reading the .explain() OutputMongoDB
 

Tendances (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
 

Similaire à Internal DSLs

Internal DSLs Scala
Internal DSLs ScalaInternal DSLs Scala
Internal DSLs Scalazefhemel
 
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.pdfshyamsunder1211
 
Wicket KT part 2
Wicket KT part 2Wicket KT part 2
Wicket KT part 2stuq
 
20160616技術會議
20160616技術會議20160616技術會議
20160616技術會議Jason Kuan
 
知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tipsikeyat
 
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.pdfShaiAlmog1
 
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.pdffeetshoemart
 
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
 
Database handling with room
Database handling with roomDatabase handling with room
Database handling with roomSergi Martínez
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в JavaDEVTYPE
 
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.docxDIPESH30
 

Similaire à 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
 

Plus de zefhemel

Docker ecosystem
Docker ecosystemDocker ecosystem
Docker ecosystemzefhemel
 
Expand your horizons
Expand your horizonsExpand your horizons
Expand your horizonszefhemel
 
Avoiding JavaScript Pitfalls Through Tree Hugging
Avoiding JavaScript Pitfalls Through Tree HuggingAvoiding JavaScript Pitfalls Through Tree Hugging
Avoiding JavaScript Pitfalls Through Tree Huggingzefhemel
 
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
 
PIL - A Platform Independent Language
PIL - A Platform Independent LanguagePIL - A Platform Independent Language
PIL - A Platform Independent Languagezefhemel
 
WebWorkFlow
WebWorkFlowWebWorkFlow
WebWorkFlowzefhemel
 
Abstractie (Dutch)
Abstractie (Dutch)Abstractie (Dutch)
Abstractie (Dutch)zefhemel
 

Plus de 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
 

Dernier

Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 

Dernier (20)

Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 

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