Commit ce13211d authored by Dave Cooper's avatar Dave Cooper
Browse files

added TUD slides, updated g102 slides.

parent aa1eea02
;; Copyright 2002, 2009 Genworks International
;; with thanks to the Delft University of Technology for sponsorship
;; of these training materials.
;; This source file is part of the General-purpose Declarative
;; Language project (GenDL).
;; This source file contains free software: you can redistribute it
;; and/or modify it under the terms of the GNU Affero General Public
;; License as published by the Free Software Foundation, either
;; version 3 of the License, or (at your option) any later version.
;; This source file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; Affero General Public License for more details.
;; You should have received a copy of the GNU Affero General Public
;; License along with this source file. If not, see
;; <>.
(in-package :training-g102-tud)
(defmacro with-htm (&body body)
`(with-cl-who-string () ,@body))
(define-object assembly (slide-show-node)
((title "G102 Supplement: GenDL Quickstart for TU Delft")
(slide-package (find-package :training-g102-tud))
(image-base-url "/g102-tud/images/")
(images-path *images-path*)
(style-url "/static/gwl/style/top.css"))
(objects :type 'objects)
(define-object objects (slide-show-leaf)
((strings-for-display "Aero Object Examples")
`((:title "Empty Surface Mixin"
((:description "Define an Empty Surface - will use real built-in surface later"
((:define-object gdl-user::empty-surface)))
(:description ,(with-cl-who-string
((:span :class "gdl-operator") "define-object") " - main operator used in GenDL to create definitions."))
(:description ,(with-cl-who-string
((:span :class "gdl-object-def") "empty-surface") " - Name of our new definition."))
(:description ,(with-cl-who-string
((:span :class "gdl-object-def") "base-object") " - Name of single mixin (should be pre-defined)."))))
(:title "Basic Wing Skeleton"
((:description "Define a wing with initial slots, mixes in empty surface to start with"
((:define-object gdl-user::wing)))
(:description ,(with-cl-who-string
((:span :class "gdl-object-def") "wing") " - our new definition name."))
(:description ,(with-cl-who-string
((:span :class "gdl-object-def") "empty-surface") " - Name of single mixin (which we already defined)."))
(:description ,(with-cl-who-string
((:span :class "gdl-section-keyword") ":computed-slots") " - constant and computed values which can be
\"answered\" by instances of this definition."))))
(:title ,(with-cl-who-string
((:span :class "gdl-section-keyword") ":computed-slots"))
((:description "Each slot is given as its own list:"
((:define-object gdl-user::wing)))))
(:description ,(with-cl-who-string
"Each list contains "
(:ul (:li "its name --- e.g. "
((:span :class "gdl-message-name") "c-avg")
" is a name, and")
(:li "its expression --- e.g. "
((:span :class "gdl-object-def") "(/ (+ (the c-root) (the c-tip)) 2)")
" is an expression."))))
(:description "The expression can be either a constant value, or an expression which computes a value on-demand.")))
(:title "Making and Using Objects on Command-line (REPL)"
((:description "Set a toplevel variable to an object:"
:examples ((:code (setq obj (make-object 'wing)))))
(:description "Then ask it a question (i.e. \"send it a message\"):"
:examples ((:code (the-object obj taper)
:return-value 1/2)))
(:description "Note the rational number (1/2) as a return value.")))
(:title "Using self to Avoid the Need for the-object"
((:description "Two ways to set self to a new object:"
((:code (setq self (make-object 'wing)))
(:code (make-self 'wing))))
(:description ,(with-htm "Now you can just use "
((:span :class "gdl-operator") "the")
" instead of "
((:span :class "gdl-operator") "the-object object..."))
((:code (the taper))
(:return-value 1/2)))
(:description ,(with-htm ((:span :class "gdl-object-def") "self")
" is set automatically within scope of "
((:span :class "define-object") "self") "."))
(:description "So there is heavy use of \"the\" inside most object definitions:"
((:define-object gdl-user::wing)))))
(:title "Making and Using Objects in \"tasty\""
((:description "Visit http://localhost:9000/tasty"
:image-url "tasty-wing-entry.png")
(:description "This creates an instance of wing and shows you different views of it.")))
(:title "Components of Tasty"
((:description ,(with-htm "Tree:" (:ul (:li "expand/condense")
(:li "perform selected \"click-mode\" action")
(:li "root node is your instance")
(:li "select click-mode from Tree menu"))))
(:description ,(with-htm "Inspector:" (:ul (:li "View slots of an object")
(:li "Drill-down into list and sequence values")
(:li "Modify settable slots"))))
(:description ,(with-htm "Viewport:" (:ul (:li "Graphical visualization")
(:li "Select format from View menu")
(:li "x3dom currently needs browser refresh")))
:image-url "tasty-wing.png")
(:title "\"Breaking\" on an object"
((:description ,(with-htm "You can use the break icon ("
((:img :src (format nil "~abreak-icon.png" (the image-base-url))))
") to set "
((:span :class "lisp-code") "self")
" to the next-clicked object"))
(:description "The concept of \"break\" is from Olden Times when browser could not work at the same time as command repl.")
(:description ,(with-htm "Click on the "
((:img :src (format nil "~abreak-icon.png" (the image-base-url))))
" and then on the "
((:img :src (format nil "~awing-in-tree.png" (the image-base-url))))
", then you can work with that wing instance as "
((:span :class "lisp-code") "self")
" on the command repl:")
:examples ((:code (the taper)
:return-value 1/2)))))
(:title ,(with-htm ((:span :class "gdl-section-keyword") ":input-slots"))
((:description ,(with-htm "You can specify "
((:span :class "gdl-section-keyword") ":input-slots")
" to be able to give values to certain slots at the time of an object's birth.")
:image-url "uml-2-8.png"
:examples ((:define-object gdl-user::wing-with-input)))))
(:title ,(with-htm ((:span :class "gdl-section-keyword") ":input-slots"))
((:description ,(with-htm
((:span :class "lisp-code") "(")
((:span :class "gdl-message-name") "a")
((:span :class "gdl-comment") " ;; Required input - no default value")
((:span :class "lisp-code") "(")
((:span :class "gdl-message-name") "b")
((:span :class "lisp-code") ")")
((:span :class "gdl-comment") " ;; optional - default is nil")
((:span :class "lisp-code") "(")
((:span :class "gdl-message-name") "c 10")
((:span :class "lisp-code") ")")
((:span :class "gdl-comment") " ;; optional - default is 10")
((:span :class "lisp-code") "(")
((:span :class "gdl-message-name") "d 20 :settable")
((:span :class "lisp-code") "))")
((:span :class "gdl-comment") " ;; optional - default is 20, can be \"bashed\"")))))
(:title "Wing with more Inputs"
((:description "This wing has two settable input-slots"
:image-url "uml-2-9c.png"
:examples ((:define-object gdl-user::wing-more-inputs)))))
(:title "Open it in Tasty"
((:description "Visit http://localhost:9000/tasty")
(:description ,(with-htm "Specify " ((:span :class "lisp-code") "wing-more-inputs") " as the Class Type")
:image-url "wing-more-inputs-tasty.png")))
(:title "Exercise 1: make a Fuselage object"
((:description ,(with-htm "Parameters (i.e. Inputs):"
(:ul (:li "diameter (d)")
(:li "length (l)"))))
(:description ,(with-htm "Outputs:"
(:ul (:li "volume (V)")
(:li "wetted surface (Sw)")
(:li "slenderness-ratio (= l / d)"))))))
(:title "How it should look in Tasty"
((:description "Like this:"
:image-url "fuselage-tasty.png")))
(:title "Exercise 1 Solution"
((:description "Don't look at this until You Try It:"
:image-url "uml-2-10b.png"
((:define-object gdl-user::fuselage)))))
(:title "Child Object in a Sequence"
:bullet-points ((:description "UML \"Has-a\" relationship"
:image-url "uml-2-12.png"
:examples ((:define-objet gdl-user::engine)
(:define-object gdl-user::wing-with-engines)))))
(:title "How it might look in Tasty"
:bullet-points ((:description "Something like this:"
:image-url "wing-with-engines-tasty.png")))
(:title "Working with Sequences"
:bullet-points ((:description ,(with-htm ((:span :class "lisp-code") "list-elements")
" converts a sequence into a Lisp list."))
(:description "Try these after \"breaking\" on a wing-with-engines:"
((:code (list-elements (the engines))
:return-value (engine-x24a47d42 engine-x24a47f9a engine-x24a481c2 engine-x24a483ea))
(:code (list-elements (the engines) (the-element Tmax))
:return-value (1000 800 900 1200))))
(:description "Access an element with direct index referencing"
((:code (the (engines 2))
:return-value engine-x24a481c2)
(:code (the (engines 2) Tmax)
:return-value 900)))
(:description ,(with-htm "Using "
((:span :class "lisp-code") "nth")
" with "
((:span :class "lisp-code") "list-elements")
" also works, but is less efficient")
((:code (nth 2 (list-elements (the engines)))
:return-value engine-x24a481c2)
(:code (the-object (nth 2 (list-elements (the engines))) Tmax)
:return-value 900)))))
(:title "Lisp background: <i>Plists</i>"
:bullet-points ((:description "Property Lisp, a type of <i>map</i>")
(:description "This is a list of pairs")
(:description "Maps keyword symbols (i.e. names) to values")
(:description ,(with-htm "Use " ((:span :class "lisp-code") "getf")
" to access a value for a given keyword:")
:examples ((:code (setq list (list :a 1 :b 2 :c 3))
:return-value (:a 1 :b 2 :c 3))
(:code (getf list :b)
:return-value 2)
(:code (getf list :c)
:return-value 3)
(:code (getf list :d)
:return-value nil)))))
(:title "Exercise 2"
:bullet-points ((:description "Define an object representing a fuel tank.")
(:description ,(with-htm "Parameters (i.e. " ((:span :class :gdl-section-keyword) "input-slots")
") are:"
(:ul (:li ((:span :class :gdl-message-name) "h"))
(:li ((:span :class :gdl-message-name) "w"))
(:li ((:span :class :gdl-message-name) "l")))))
(:description ,(with-htm "Include a method (i.e. " ((:span :class :gdl-section-keyword) "computed-slot")
") to calculate the "
((:span :class :gdl-message-name) "volume") "."))
(:description ,(with-htm "Add a sequence of "
((:span :class :gdl-message-name) "fuel-tanks")
" in the wing-with-engines, driven by the following plist:")
((:code (list (list :w 4 :l 3.5 :h 0.3 )
(list :w 2 :l 2.5 :h 0.2 )
(list :w 1.5 :l 2 :h 0.15)))))))
(:title "Solution, Part 1"
:bullet-points ((:description "First, our fuel tank definition:"
:image-url "uml-sol2.png"a
((:define-object gdl-user::fuel-tank)))))
(:title "Solution, Part 2"
:bullet-points ((:description "Then, our wing definition:"
:image-url "uml-sol2-contd.png"
((:define-object gdl-user::wing-with-tanks)))
(:description "Yes, there is a shorter way to do the inputs for the fuel-tank object (but do it the long way for now).")))
(:title "How it might look in Tasty"
:bullet-points ((:description "Something like this:"
:image-url "wing-tanks-tasty.png")))
(:title "GenDL Functions"
((:description "All the fun of Lisp Functions and GenDL Objects, rolled up into one!")
(:description "Aircraft assembly with friction force function:"
:image-url "uml-2-15.png"
((:define-object gdl-user::aircraft)))))
(:title "Calling GenDL Functions"
((:description "With make-object on command repl:"
((:code (setq obj (make-object 'aircraft)))
(:code (the-object obj (compute-friction-force 50))
:return-value 5903.793955680823)
(:code (the-object obj (compute-friction-force 150))
:return-value 53134.145601127406)))
(:description "After break/set-self in tasty")
(:description "Procedurally from within another function")))
(:title "Exercise 3"
((:description ,(with-htm "Add a function " ((:span :class :gdl-message-name) "lift")
" to the aircraft class."))
(:description ,(with-htm "Your function should accept "
((:span :class :lisp-code) "speed")
" and "
((:span :class :lisp-code) "C-of-L")
" as its arguments, and should yield the value of "
((:span :class :gdl-message-name) "lift") "."))
(:description ,(with-htm "Test the function for the following values of C-of-L:"
((:span :class :lisp-code) "(0.15 0.18 0.20 0.22 0.25)")))
(:description "Compare with your neighbor.")))
(:title "Solution"
((:description "Note that this could also mix-in the original aircraft, and avoid the repeated code"
:image-url "uml-2-17.png"
:examples ((:define-object gdl-user::aircraft-with-lift)))))
(:title "Today's Cumulative UML object Tree"
((:description ,(with-htm ((:span :class :lisp-code) "My-B52") " can mix-in and extend "
((:span :class :lisp-code) "aircraft-with-lift") ".")
:image-url "final-uml.png")))))))
\ No newline at end of file
(in-package :common-lisp-user)
(gwl:define-package :training-g102-tud (:use :slide-show) (:export #:assembly #:push!))
(in-package :training-g102-tud)
(publish :path "/training-g102-tud"
:function #'(lambda(req ent)
(gwl-make-object req ent "training-g102-tud:assembly")))
(print-variables *load-truename*)
(defparameter *images-path* (merge-pathnames "g102-tud/images/" (glisp:system-home :gdl-training)))
(publish-directory :prefix "/g102-tud/images/"
:destination (format nil "~a" *images-path*))
(defun push! ()
(glisp:run-shell-command "rm -r /tmp/sites/")
(gwl:crawl "training-g102-tud:assembly")
(glisp:run-shell-command "mv /tmp/sites/assembly/ /tmp/sites/training-g102-tud/")
(glisp:run-shell-command "rsync -zav /tmp/sites/training-g102-tud/")
(glisp:run-shell-command "rm -r /tmp/sites/"))
\ No newline at end of file
\ No newline at end of file
;; Copyright 20012 Genworks International
;; Copyright 2012 Genworks International
;; This source file is part of the General-purpose Declarative
;; Language project (GDL).
This diff is collapsed.
;; Copyright 20012 Genworks International
;; Copyright 2012 Genworks International
;; This source file is part of the General-purpose Declarative
;; Language project (GDL).
......@@ -33,17 +33,23 @@
(:title "Topics Covered in G102" :bullet-points
((:description "Objects in Gendl and the <span class=gdl-operator>define-object</span> operator")
((:description ,(with-cl-who-string
"Objects in Gendl and the " ((:span :class "gdl-operator") "define-object") " operator"
(:ul (:li "Debugging (basic)")
(:li "Inspection & Visualization (tasty)"))))
(:description ,(with-output-to-string (ss)
"Geometry and Coordinate Systems"
(:ul (:li "Wireframe")
(:li "Surfaces/Curves")
(:ul (:li "Points")
(:li "Curves")
(:li "Surfaces")
(:li "Solids")))))
(:description "Custom User Interfaces")
(:description "Custom User Interfaces (optional)")
(:description "Interacting with the Outside World")
(:description "Debugging and Performance")))
(:description "Debugging and Performance (detailed)")))
(:title "What is Gendl?" :bullet-points
((:description "A Dynamic, Declarative, Object-oriented
......@@ -52,23 +58,6 @@ language environment embedded in Common Lisp")
problems and their solutions using an intuitive, straightforward structure")
(:description "A cross-platform server solution for web application deployment")))
(:title "What are Dynamic, Declarative, Object-oriented?"
((:description "The system is <i>Dynamic</i> vs. <i>Static</i> on several levels:
<li>Change code (definitions) and compile/load without restarting your model
<li>Define variables/slots without the need for predefined data types (dynamic vs. static typing)
<li>Modify slot values <i>and even object types</i> at runtime
(:description "Definitions in Gendl have no \"begin\" or \"end\" - they are specified <i>declaratively</i>, in whatever order is convenient.")
(:description "All standard OO features plus several advanced ones:
<li> Clear separation between the <i>definition</i> of an object and an <i>instance</i> (the object itself)</li>
<li> Multiple Inheritance: the ability for one definition to have several <i>superclasses</i></li>
<li> Message-passing (object-centric) and Generic Function (method-centric) styles
<li> Meta-object protocol (MOP): definitions themselves are also first-class objects</li>
<li> Reflection: ability for an object to generate documentation and source code for itself</li>
(:title "A Path of Discovery: Gendl as a Learning Tool"
......@@ -90,36 +90,35 @@ into the function <span class=lisp-code>+</span> to yield the result which is <s
,(with-output-to-string (ss)
ss "Purpose in Life"
((:table :border 1)
(:tr ((:th :width 0.5 :background "#BBDDFF") "<br>")
((:th :width 0.5 :background "#BBFFDD")
(:tr ((:th :width 0.5))
((:th :width 0.5 )
"Function (Common Lisp)")
((:th :width 0.5 :background "#BBFFDD")
((:th :width 0.5 )
"Object (Gendl)"))
(:td (:b "Typical Purpose"))
((:td :background "#CCEEFF")
"Accepts some " (:i "arguments")
", possibly performs some "
(:i "side-effects")
", and computes a "
(:i "return-value"))
((:td :background "#CCEEFF")
"Accepts some "
(:i "inputs")
", possibly performs some "
(:i "side-effects")
", and computes a set of "
(:i "outputs")))
((:td :bgcolor (lookup-color :aquamarine :format :hex)
:colspan 2)
(:li "Accept some "
(:i "inputs"))
(:li "possibly performs some "
(:i "side-effects"))
(:li "compute one or more "
(:i "outputs")))))
(:td (:b "How to Use"))
((:td :background "#CCEEFF")
((:td :bgcolor (lookup-color :thistle :format :hex))
"You call it by name, by evaluating a Lisp expression")
((:td :background "#CCEEFF")
((:td :bgcolor (lookup-color :aquamarine :format :hex))
(:ol (:li "You create or retrieve an " (:i "object"))