Design Your Own Domain Specific Language
This talk examines how dynamic languages in general and Groovy in particular provide toos to help design programming languages that are closer of the natural language of the target subject matter expert. It offers many features that allow you to create embedded DSLs: Closures, compile-time and run-time metaprogramming, operator overloading, named arguments, a more concise and expressive syntax and more.
From Programming to Modeling And Back AgainMarkus Voelter
Is programming = modeling? Are there differences, conceptual and tool-wise? Should there be differences? What if we programmed the way we model? Or vice versa? In this slidedeck I explore this question and introduce interesting developments in the space of projectional editing and modern parser technology. This leads to the concept of modular programming languages and a new way of looking at programming. I will demonstrate the idea with tools that are available today, for example TMF Xtext, JetBrains MPS and Intentional’s Domain Workbench.
Architecture DSLs are a useful tool to capture the cornerstones of platform or product line architectures. In addition, interesting analyses can be performed on the models, and much of the infrastructure and configuration code can be generated. On the flip side, these DSLs themselves must be architected consciously: while many architectural abstractions are specific to any given platform or product line, many other aspects are generic and hence can be reused for several architecture DSLs. In this talk I trace how my thinking on architecture modeling has changed over time, and how this is reflected in the architecture DSLs I have built (or helped to build), and how evolving tools have made these changes possible.
Intermediate languages are used in compiler construction to simplify retargeting compilers to multiple machine architectures. In the implementation of \emph{domain-specific languages} (DSLs), compilers typically generate high-level source code, rather than low-level machine instructions. DSL compilers target a software platform, i.e. a programming language with a set of libraries, deployable on one or more operating systems. DSLs enable targeting \emph{multiple} software platforms if its abstractions are platform independent. While transformations from DSL to each targeted platform are often conceptually very similar, there is little reuse between transformations due to syntactic and API differences of the target platforms, making supporting multiple platforms expensive. In this paper, we discuss the design and implementation of PIL, a Platform Independent Language, an intermediate language providing a layer of abstraction between DSL and target platform code, abstracting from syntactic and API differences between platforms, thereby removing the need for platform-specific transformations. We discuss the use of PIL in an implemementation of WebDSL, a DSL for building web applications.
From Programming to Modeling And Back AgainMarkus Voelter
Is programming = modeling? Are there differences, conceptual and tool-wise? Should there be differences? What if we programmed the way we model? Or vice versa? In this slidedeck I explore this question and introduce interesting developments in the space of projectional editing and modern parser technology. This leads to the concept of modular programming languages and a new way of looking at programming. I will demonstrate the idea with tools that are available today, for example TMF Xtext, JetBrains MPS and Intentional’s Domain Workbench.
Architecture DSLs are a useful tool to capture the cornerstones of platform or product line architectures. In addition, interesting analyses can be performed on the models, and much of the infrastructure and configuration code can be generated. On the flip side, these DSLs themselves must be architected consciously: while many architectural abstractions are specific to any given platform or product line, many other aspects are generic and hence can be reused for several architecture DSLs. In this talk I trace how my thinking on architecture modeling has changed over time, and how this is reflected in the architecture DSLs I have built (or helped to build), and how evolving tools have made these changes possible.
Intermediate languages are used in compiler construction to simplify retargeting compilers to multiple machine architectures. In the implementation of \emph{domain-specific languages} (DSLs), compilers typically generate high-level source code, rather than low-level machine instructions. DSL compilers target a software platform, i.e. a programming language with a set of libraries, deployable on one or more operating systems. DSLs enable targeting \emph{multiple} software platforms if its abstractions are platform independent. While transformations from DSL to each targeted platform are often conceptually very similar, there is little reuse between transformations due to syntactic and API differences of the target platforms, making supporting multiple platforms expensive. In this paper, we discuss the design and implementation of PIL, a Platform Independent Language, an intermediate language providing a layer of abstraction between DSL and target platform code, abstracting from syntactic and API differences between platforms, thereby removing the need for platform-specific transformations. We discuss the use of PIL in an implemementation of WebDSL, a DSL for building web applications.
HDR Defence - Software Abstractions for Parallel ArchitecturesJoel Falcou
Performing large, intensive or non-trivial computing on array like data
structures is one of the most common task in scientific computing, video game
development and other fields. This matter of fact is backed up by the large number
of tools, languages and libraries to perform such tasks. If we restrict ourselves to
C++ based solutions, more than a dozen such libraries exists from BLAS/LAPACK
C++ binding to template meta-programming based Blitz++ or Eigen.
If all of these libraries provide good performance or good abstraction, none of
them seems to fit the need of so many different user types. Moreover, as parallel
system complexity grows, the need to maintain all those components quickly
become unwieldy. This thesis explores various software design techniques - like
Generative Programming, MetaProgramming and Generic Programming - and their
application to the implementation of various parallel computing libraries in such a
way that abstraction and expressiveness are maximized while efficiency overhead is
minimized.
Tools and practices to help you deal with legacy codeDennis Doomen
We all love to build greenfield projects, but the reality is that in most jobs you have to deal with a lot of legacy code. This doesn't mean the code is bad. It just means that choices were made that were the right ones at that time, or that the developers were not entire up-to-date with modern development practices. And that's exactly what this talk is about. I enjoy taking such a codebase and gradually introduce architectural seems, add a proper build pipeline, introduce temporary tests and then gradually refactor the codebase to combine more maintainable, testable and reliable. So in this talk, I'd like to unfold my extensive toolbox of practices, principles, tools and mindset to help you improve your legacy code without jeopardizing your business.
Understand production environment
See which vinaries are running in production and what config files are used
Verify the code and the production release are in sync, e.g. DotPeek
Analyze logs to understand what features are used
Try to get it to run on a local environment
Understand code
Generate project diagrams and class hierarchies
Find origin calls and destination of a parameter using Rider
Use navigation options to find inheritors, usages, etc.
Use the namespaces and project names to understand the relation
Have Rider's AI Assistant or ChatGPT explain the code
Track all documentation in a single place
Build C4 diagrams
Find dead code
Reduce the scope of types and members to internal to find more dead code
Detect code inefficiencies and dead code using Rider
Remove commented out code
Build a safety net
If therea are tests, add code coverage reporting using Coverlet and use that to find dark spots
(HTTP API) Characteristics tests using FluentAssertions, Bogus, xUnit. Use AI to generate them. It's fine, you'll delete them later on
Use test containers for .net t lo include the databse
Build a couple of end to end UI tests e.g. using Cypress, Playwright, efc
Improve deployability
Add scripts or builds steps to run the code locally, Nuke build pipeline to get consistency
Adopt a version strategy and name branches accordingly
Adopt automatic versioning using GitVersion
Adopt logging and exception strategy, e.g. Serilog
Pulumi to automate PR deployments
Improve code
Treat all warnings as errors and fix thhem
Editorconfig / eslint so auto-format works
Configure a personal Rider/R# clean-up profile to auto-format file, project and solution
Roslyn analyzers
Microsoft.CodeAnalysis.BannedApiAnalyzers
StyleCop.Analyzers
CSharpGuidelinesAnalyzer
Roslynator.Analyzers
Meziantou.Analyzer
Enable nullable types per file
Move new code to .NET 6+ or cross-compile
Switch to newer C# versions, possibly using Polysharp
File-scope namespaces
Target-typed news
switch expression
String interpolation instead of string.format
Use Directory.Build.Props to reduce duplication
Improve naming whenever you can
Encapsulate prim itive types and collections in d
Game Programming 04 - Style & Design PrinciplesNick Pruehs
Chapter 4 of the lecture Game Programming taught at HAW Hamburg.
Introduction to naming conventions, type and member design, exception design and common .NET interfaces.
Scripting experts from Inductive Automation cover general best practices that will help you add flexibility and customization to HMI, SCADA, IIoT, and other industrial applications. Some specific tips about using scripting in the Ignition platform will be included as well.
In this webinar, learn more about:
• Common scripting pitfalls and how to avoid them
• The best programming languages to use
• Things to consider before using scripting
• How scripting environments work
• Scripting timesavers
• And more
Chapter 01 of the lecture Style & Design Principles taught at SAE Institute Hamburg.
Introduction to naming conventions, type and member design, exception design and common .NET interfaces.
Software Engineering Thailand: Programming with ScalaBrian Topping
Meet-up, May 28, 2015, Launchpad, Bangkok. http://www.meetup.com/Software-Engineering-Thailand/events/222548484/.
Apologies for the rendering quality not matching the presentation, I did these with Apple Keynote and Slideshare does not support this format. I will try to edit them when there is more time.
Thanks to Bangkok LaunchPad (https://www.facebook.com/launchpadhq) for generously hosting this event!
(Costless) Software Abstractions for Parallel ArchitecturesJoel Falcou
Performing large, intensive or non-trivial computing on array like data structures is one of the most common task in scientific computing, video game development and other fields. This matter of fact is backed up by the large number of tools, languages and libraries to perform such tasks. If we restrict ourselves to C++ based solutions, more than a dozen such libraries exists from BLAS/LAPACK C++ binding to template meta-programming based Blitz++ or Eigen. If all of these libraries provide good performance or good abstraction, none of them seems to fit the need of so many different user types.
Moreover, as parallel system complexity grows, the need to maintain all those components quickly become unwieldy. This talk explores various software design techniques - like Generative Programming, MetaProgramming and Generic Programming - and their application to the implementation of a parallel computing librariy in such a way that:
- abstraction and expressiveness are maximized - cost over efficiency is minimized
We'll skim over various applications and see how they can benefit from such tools. We will conclude by discussing what lessons were learnt from this kind of implementation and how those lessons can translate into new directions for the language itself.
HDR Defence - Software Abstractions for Parallel ArchitecturesJoel Falcou
Performing large, intensive or non-trivial computing on array like data
structures is one of the most common task in scientific computing, video game
development and other fields. This matter of fact is backed up by the large number
of tools, languages and libraries to perform such tasks. If we restrict ourselves to
C++ based solutions, more than a dozen such libraries exists from BLAS/LAPACK
C++ binding to template meta-programming based Blitz++ or Eigen.
If all of these libraries provide good performance or good abstraction, none of
them seems to fit the need of so many different user types. Moreover, as parallel
system complexity grows, the need to maintain all those components quickly
become unwieldy. This thesis explores various software design techniques - like
Generative Programming, MetaProgramming and Generic Programming - and their
application to the implementation of various parallel computing libraries in such a
way that abstraction and expressiveness are maximized while efficiency overhead is
minimized.
Tools and practices to help you deal with legacy codeDennis Doomen
We all love to build greenfield projects, but the reality is that in most jobs you have to deal with a lot of legacy code. This doesn't mean the code is bad. It just means that choices were made that were the right ones at that time, or that the developers were not entire up-to-date with modern development practices. And that's exactly what this talk is about. I enjoy taking such a codebase and gradually introduce architectural seems, add a proper build pipeline, introduce temporary tests and then gradually refactor the codebase to combine more maintainable, testable and reliable. So in this talk, I'd like to unfold my extensive toolbox of practices, principles, tools and mindset to help you improve your legacy code without jeopardizing your business.
Understand production environment
See which vinaries are running in production and what config files are used
Verify the code and the production release are in sync, e.g. DotPeek
Analyze logs to understand what features are used
Try to get it to run on a local environment
Understand code
Generate project diagrams and class hierarchies
Find origin calls and destination of a parameter using Rider
Use navigation options to find inheritors, usages, etc.
Use the namespaces and project names to understand the relation
Have Rider's AI Assistant or ChatGPT explain the code
Track all documentation in a single place
Build C4 diagrams
Find dead code
Reduce the scope of types and members to internal to find more dead code
Detect code inefficiencies and dead code using Rider
Remove commented out code
Build a safety net
If therea are tests, add code coverage reporting using Coverlet and use that to find dark spots
(HTTP API) Characteristics tests using FluentAssertions, Bogus, xUnit. Use AI to generate them. It's fine, you'll delete them later on
Use test containers for .net t lo include the databse
Build a couple of end to end UI tests e.g. using Cypress, Playwright, efc
Improve deployability
Add scripts or builds steps to run the code locally, Nuke build pipeline to get consistency
Adopt a version strategy and name branches accordingly
Adopt automatic versioning using GitVersion
Adopt logging and exception strategy, e.g. Serilog
Pulumi to automate PR deployments
Improve code
Treat all warnings as errors and fix thhem
Editorconfig / eslint so auto-format works
Configure a personal Rider/R# clean-up profile to auto-format file, project and solution
Roslyn analyzers
Microsoft.CodeAnalysis.BannedApiAnalyzers
StyleCop.Analyzers
CSharpGuidelinesAnalyzer
Roslynator.Analyzers
Meziantou.Analyzer
Enable nullable types per file
Move new code to .NET 6+ or cross-compile
Switch to newer C# versions, possibly using Polysharp
File-scope namespaces
Target-typed news
switch expression
String interpolation instead of string.format
Use Directory.Build.Props to reduce duplication
Improve naming whenever you can
Encapsulate prim itive types and collections in d
Game Programming 04 - Style & Design PrinciplesNick Pruehs
Chapter 4 of the lecture Game Programming taught at HAW Hamburg.
Introduction to naming conventions, type and member design, exception design and common .NET interfaces.
Scripting experts from Inductive Automation cover general best practices that will help you add flexibility and customization to HMI, SCADA, IIoT, and other industrial applications. Some specific tips about using scripting in the Ignition platform will be included as well.
In this webinar, learn more about:
• Common scripting pitfalls and how to avoid them
• The best programming languages to use
• Things to consider before using scripting
• How scripting environments work
• Scripting timesavers
• And more
Chapter 01 of the lecture Style & Design Principles taught at SAE Institute Hamburg.
Introduction to naming conventions, type and member design, exception design and common .NET interfaces.
Software Engineering Thailand: Programming with ScalaBrian Topping
Meet-up, May 28, 2015, Launchpad, Bangkok. http://www.meetup.com/Software-Engineering-Thailand/events/222548484/.
Apologies for the rendering quality not matching the presentation, I did these with Apple Keynote and Slideshare does not support this format. I will try to edit them when there is more time.
Thanks to Bangkok LaunchPad (https://www.facebook.com/launchpadhq) for generously hosting this event!
(Costless) Software Abstractions for Parallel ArchitecturesJoel Falcou
Performing large, intensive or non-trivial computing on array like data structures is one of the most common task in scientific computing, video game development and other fields. This matter of fact is backed up by the large number of tools, languages and libraries to perform such tasks. If we restrict ourselves to C++ based solutions, more than a dozen such libraries exists from BLAS/LAPACK C++ binding to template meta-programming based Blitz++ or Eigen. If all of these libraries provide good performance or good abstraction, none of them seems to fit the need of so many different user types.
Moreover, as parallel system complexity grows, the need to maintain all those components quickly become unwieldy. This talk explores various software design techniques - like Generative Programming, MetaProgramming and Generic Programming - and their application to the implementation of a parallel computing librariy in such a way that:
- abstraction and expressiveness are maximized - cost over efficiency is minimized
We'll skim over various applications and see how they can benefit from such tools. We will conclude by discussing what lessons were learnt from this kind of implementation and how those lessons can translate into new directions for the language itself.
Scripting experts from Inductive Automation cover general best practices that will help you add flexibility and customization to HMI, SCADA, IIoT, and other industrial applications. Some specific tips about using scripting in the Ignition platform will be included as well.
In this webinar, learn more about:
• Common scripting pitfalls and how to avoid them
• The best programming languages to use
• Things to consider before using scripting
• How scripting environments work
• Scripting timesavers
• And more
[Gophercon 2019] Analysing code quality with linters and static analysisWeverton Timoteo
How do you define a "good code"? How to write high-quality software with assistance of linters and static analysis.
Using golint, govet and gofmt can improve our code.
Simple Ruby DSL Techniques: Big Project Impact!Aman King
Talk that introduces simple DSL techniques in Ruby. Developers are encouraged to apply such techniques for their project's business domain to gain benefits usually received from DSL-ish APIs of frameworks.
Presented at Garden City RubyConf 2014 in Bangalore, India.
Devel::NYTProf 2009-07 (OUTDATED, see 201008)Tim Bunce
The slides of my "State-of-the-art Profiling with Devel::NYTProf" talk at OSCON in July 2009.
I'll upload a screencast and give the link in a blog post at http://blog.timbunce.org
There are tactical reasons to adopt strong typehint: easy validation, less code, fashionable. Besides, the first typehints blend in effortlessly with the current application: it is as if typehint was already there. Later, it appears that scalar types paved the way to more substantial code refactoring. Classes emerge from the initial scalar types, code congregate around important values, types gets more complex. Finally, systemic typehint arrives. Type hints become systemic when they help tame the class dependency hell, and help us plan for the new code. During the session, we'll cover the various stages of using typehints, with their advantages, and when not to overuse them.
Fort de ses 1.7 millions de téléchargements l'an passé, Groovy continue son bonhomme de chemin en tête parmi les langages de programmation alternatifs pour la JVM.
Groovy 2.0, sorti l'an passé, introduisait dans son offre de la modularité, le support de JDK 7 au niveau syntaxique avec "Project Coin" autant qu'au niveau JVM avec l'utilisation d'"invoke dynamic", et proposait des fonctionnalités de typage et de compilation statique.
Groovy 2.1, quant à lui, s'appuie sur ces bases pour compléter le support d'"invoke dynamic" pour plus de performances. Il propose des améliorations permettant de documenter, d'aider les IDEs, et de vérifier statiquement les Domain-Specific Languages construits avec Groovy. Vous pourrez créer des méta-annotations regroupant d'autres annotations, pour éviter l'annotation "hell". Et enfin, vous irez encore plus loin dans la customisation du compilateur !
Accrochez votre ceinture, paré au décollage !
"Groovy 2.0 and beyond" presentation given at the Groovy/Grails eXchange conference.
Video can be seen here:
http://skillsmatter.com/podcast/groovy-grails/keynote-speech
Groovy Domain Specific Languages - SpringOne2GX 2012Guillaume Laforge
Paul King, Andrew Eisenberg and Guillaume Laforge present about implementation of Domain-Specific Languages in Groovy, while at the SpringOne2GX 2012 conference in Washington DC.
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualityInflectra
In this insightful webinar, Inflectra explores how artificial intelligence (AI) is transforming software development and testing. Discover how AI-powered tools are revolutionizing every stage of the software development lifecycle (SDLC), from design and prototyping to testing, deployment, and monitoring.
Learn about:
• The Future of Testing: How AI is shifting testing towards verification, analysis, and higher-level skills, while reducing repetitive tasks.
• Test Automation: How AI-powered test case generation, optimization, and self-healing tests are making testing more efficient and effective.
• Visual Testing: Explore the emerging capabilities of AI in visual testing and how it's set to revolutionize UI verification.
• Inflectra's AI Solutions: See demonstrations of Inflectra's cutting-edge AI tools like the ChatGPT plugin and Azure Open AI platform, designed to streamline your testing process.
Whether you're a developer, tester, or QA professional, this webinar will give you valuable insights into how AI is shaping the future of software delivery.
UiPath Test Automation using UiPath Test Suite series, part 4DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 4. In this session, we will cover Test Manager overview along with SAP heatmap.
The UiPath Test Manager overview with SAP heatmap webinar offers a concise yet comprehensive exploration of the role of a Test Manager within SAP environments, coupled with the utilization of heatmaps for effective testing strategies.
Participants will gain insights into the responsibilities, challenges, and best practices associated with test management in SAP projects. Additionally, the webinar delves into the significance of heatmaps as a visual aid for identifying testing priorities, areas of risk, and resource allocation within SAP landscapes. Through this session, attendees can expect to enhance their understanding of test management principles while learning practical approaches to optimize testing processes in SAP environments using heatmap visualization techniques
What will you get from this session?
1. Insights into SAP testing best practices
2. Heatmap utilization for testing
3. Optimization of testing processes
4. Demo
Topics covered:
Execution from the test manager
Orchestrator execution result
Defect reporting
SAP heatmap example with demo
Speaker:
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
Key Trends Shaping the Future of Infrastructure.pdfCheryl Hung
Keynote at DIGIT West Expo, Glasgow on 29 May 2024.
Cheryl Hung, ochery.com
Sr Director, Infrastructure Ecosystem, Arm.
The key trends across hardware, cloud and open-source; exploring how these areas are likely to mature and develop over the short and long-term, and then considering how organisations can position themselves to adapt and thrive.
UiPath Test Automation using UiPath Test Suite series, part 3DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 3. In this session, we will cover desktop automation along with UI automation.
Topics covered:
UI automation Introduction,
UI automation Sample
Desktop automation flow
Pradeep Chinnala, Senior Consultant Automation Developer @WonderBotz and UiPath MVP
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
DevOps and Testing slides at DASA ConnectKari Kakkonen
My and Rik Marselis slides at 30.5.2024 DASA Connect conference. We discuss about what is testing, then what is agile testing and finally what is Testing in DevOps. Finally we had lovely workshop with the participants trying to find out different ways to think about quality and testing in different parts of the DevOps infinity loop.
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...James Anderson
Effective Application Security in Software Delivery lifecycle using Deployment Firewall and DBOM
The modern software delivery process (or the CI/CD process) includes many tools, distributed teams, open-source code, and cloud platforms. Constant focus on speed to release software to market, along with the traditional slow and manual security checks has caused gaps in continuous security as an important piece in the software supply chain. Today organizations feel more susceptible to external and internal cyber threats due to the vast attack surface in their applications supply chain and the lack of end-to-end governance and risk management.
The software team must secure its software delivery process to avoid vulnerability and security breaches. This needs to be achieved with existing tool chains and without extensive rework of the delivery processes. This talk will present strategies and techniques for providing visibility into the true risk of the existing vulnerabilities, preventing the introduction of security issues in the software, resolving vulnerabilities in production environments quickly, and capturing the deployment bill of materials (DBOM).
Speakers:
Bob Boule
Robert Boule is a technology enthusiast with PASSION for technology and making things work along with a knack for helping others understand how things work. He comes with around 20 years of solution engineering experience in application security, software continuous delivery, and SaaS platforms. He is known for his dynamic presentations in CI/CD and application security integrated in software delivery lifecycle.
Gopinath Rebala
Gopinath Rebala is the CTO of OpsMx, where he has overall responsibility for the machine learning and data processing architectures for Secure Software Delivery. Gopi also has a strong connection with our customers, leading design and architecture for strategic implementations. Gopi is a frequent speaker and well-known leader in continuous delivery and integrating security into software delivery.
Generating a custom Ruby SDK for your web service or Rails API using Smithyg2nightmarescribd
Have you ever wanted a Ruby client API to communicate with your web service? Smithy is a protocol-agnostic language for defining services and SDKs. Smithy Ruby is an implementation of Smithy that generates a Ruby SDK using a Smithy model. In this talk, we will explore Smithy and Smithy Ruby to learn how to generate custom feature-rich SDKs that can communicate with any web service, such as a Rails JSON API.
Neuro-symbolic is not enough, we need neuro-*semantic*Frank van Harmelen
Neuro-symbolic (NeSy) AI is on the rise. However, simply machine learning on just any symbolic structure is not sufficient to really harvest the gains of NeSy. These will only be gained when the symbolic structures have an actual semantics. I give an operational definition of semantics as “predictable inference”.
All of this illustrated with link prediction over knowledge graphs, but the argument is general.
JMeter webinar - integration with InfluxDB and GrafanaRTTS
Watch this recorded webinar about real-time monitoring of application performance. See how to integrate Apache JMeter, the open-source leader in performance testing, with InfluxDB, the open-source time-series database, and Grafana, the open-source analytics and visualization application.
In this webinar, we will review the benefits of leveraging InfluxDB and Grafana when executing load tests and demonstrate how these tools are used to visualize performance metrics.
Length: 30 minutes
Session Overview
-------------------------------------------
During this webinar, we will cover the following topics while demonstrating the integrations of JMeter, InfluxDB and Grafana:
- What out-of-the-box solutions are available for real-time monitoring JMeter tests?
- What are the benefits of integrating InfluxDB and Grafana into the load testing stack?
- Which features are provided by Grafana?
- Demonstration of InfluxDB and Grafana using a practice web application
To view the webinar recording, go to:
https://www.rttsweb.com/jmeter-integration-webinar
GraphRAG is All You need? LLM & Knowledge GraphGuy Korland
Guy Korland, CEO and Co-founder of FalkorDB, will review two articles on the integration of language models with knowledge graphs.
1. Unifying Large Language Models and Knowledge Graphs: A Roadmap.
https://arxiv.org/abs/2306.08302
2. Microsoft Research's GraphRAG paper and a review paper on various uses of knowledge graphs:
https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/
2. Guillaume Laforge
• Groovy Project Manager
• JSR-241 Spec Lead
• Head of Groovy Development
at SpringSource / VMWare
• Initiator of the Grails framework
• Creator of the Gaelyk toolkit
• Co-author of Groovy in Action
• Speaker: JavaOne, QCon, JavaZone, Sun TechDays,
Devoxx, The Spring Experience, SpringOne, JAX, Dynamic
Language World, IJTC, and more...
2
3. Guillaume Laforge
• Groovy Project Manager
• JSR-241 Spec Lead
• Head of Groovy Development
at SpringSource / VMWare
• Initiator of the Grails framework
• Creator of the Gaelyk toolkit
• Co-author of Groovy in Action
• Speaker: JavaOne, QCon, JavaZone, Sun TechDays,
Devoxx, The Spring Experience, SpringOne, JAX, Dynamic
Language World, IJTC, and more...
2
19. DSL: a potential solution?
• Use a more expressive language
than a general purpose one
• Share a common metaphore of understanding
between developers and subject matter experts
• Have domain experts help with the design
of the business logic of an application
• Avoid cluttering business code with
too much boilerplate technical code
• Cleanly separate business logic from application code
• Let business rules have their own lifecycle
18
28. Scripts vs classes
• Hide all the boilerplate technical code
– an end-user doesn’t need to know about classes
23
29. Scripts vs classes
• Hide all the boilerplate technical code
– an end-user doesn’t need to know about classes
public class Rule {
public static void main(String[] args) {
System.out.println("Hello");
}
}
23
30. Scripts vs classes
• Hide all the boilerplate technical code
– an end-user doesn’t need to know about classes
public class Rule {
public static void main(String[] args) {
System.out.println("Hello");
}
}
println "Hello"
23
31. Optional typing
• No need to bother with types or even generics
– unless you want to!
– but strongly typed if you so desire
24
32. Optional typing
• No need to bother with types or even generics
– unless you want to!
– but strongly typed if you so desire
// given this API method
public Rate<LoanType, Duration, BigDecimal>[] lookupTable() { ... }
24
33. Optional typing
• No need to bother with types or even generics
– unless you want to!
– but strongly typed if you so desire
// given this API method
public Rate<LoanType, Duration, BigDecimal>[] lookupTable() { ... }
// verbose Java notation
Rate<LoanType, Duration, BigDecimal>[] = lookupTable();
24
34. Optional typing
• No need to bother with types or even generics
– unless you want to!
– but strongly typed if you so desire
// given this API method
public Rate<LoanType, Duration, BigDecimal>[] lookupTable() { ... }
// verbose Java notation
Rate<LoanType, Duration, BigDecimal>[] = lookupTable();
// leaner Groovy variant
def table = lookupTable()
24
43. Optional parens & semis
• Make statements and expressions
look more like natural languages
26
44. Optional parens & semis
• Make statements and expressions
look more like natural languages
move(left);
26
45. Optional parens & semis
• Make statements and expressions
look more like natural languages
move(left);
move left
26
46. Named arguments
• In Groovy you can mix named and unnamed arguments for
method parameters
– named params are actually put in a map parameter
– plus optional parens & semis
take 1.pill,
of: Chloroquinine,
after: 6.hours
// Calls a method signature like:
def take(Map m, MedicineQuantity mq)
27
48. Command chains expressions
• A grammar improvement allowing you to
drop dots & parens when chaining method calls
– an extended version of top-level statements like println
28
49. Command chains expressions
• A grammar improvement allowing you to
drop dots & parens when chaining method calls
– an extended version of top-level statements like println
28
50. Command chains expressions
• A grammar improvement allowing you to
drop dots & parens when chaining method calls
– an extended version of top-level statements like println
• Less dots, less parens allow you to
– write more readable business rules
– in almost plain English sentences
• (or any language, of course)
28
51. Command chains expressions
• A grammar improvement allowing you to
drop dots & parens when chaining method calls
– an extended version of top-level statements like println
• Less dots, less parens allow you to
– write more readable business rules
– in almost plain English sentences
• (or any language, of course)
28
52. Command chains expressions
• A grammar improvement allowing you to
drop dots & parens when chaining method calls
– an extended version of top-level statements like println
• Less dots, less parens allow you to
– write more readable business rules
– in almost plain English sentences
• (or any language, of course)
• Let’s have a look at some examples
28
69. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
36
70. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
// leverage named‐args as punctuation
36
71. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
// leverage named‐args as punctuation
check that: margarita tastes good
36
72. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
// leverage named‐args as punctuation
check that: margarita tastes good
// closure parameters for new control structures
36
73. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
// leverage named‐args as punctuation
check that: margarita tastes good
// closure parameters for new control structures
given {} when {} then {}
36
74. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
// leverage named‐args as punctuation
check that: margarita tastes good
// closure parameters for new control structures
given {} when {} then {}
// zero‐arg methods require parens
36
75. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
// leverage named‐args as punctuation
check that: margarita tastes good
// closure parameters for new control structures
given {} when {} then {}
// zero‐arg methods require parens
select all unique() from names
36
76. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
// leverage named‐args as punctuation
check that: margarita tastes good
// closure parameters for new control structures
given {} when {} then {}
// zero‐arg methods require parens
select all unique() from names
// possible with an odd number of terms
36
77. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
// leverage named‐args as punctuation
check that: margarita tastes good
// closure parameters for new control structures
given {} when {} then {}
// zero‐arg methods require parens
select all unique() from names
// possible with an odd number of terms
take 3 cookies
36
78. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
( ). ( ). ( )
// leverage named‐args as punctuation
check that: margarita tastes good
// closure parameters for new control structures
given {} when {} then {}
// zero‐arg methods require parens
select all unique() from names
// possible with an odd number of terms
take 3 cookies
36
79. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
( ). ( ). ( )
// leverage named‐args as punctuation
check that: margarita tastes good
( ). ( )
// closure parameters for new control structures
given {} when {} then {}
// zero‐arg methods require parens
select all unique() from names
// possible with an odd number of terms
take 3 cookies
36
80. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
( ). ( ). ( )
// leverage named‐args as punctuation
check that: margarita tastes good
( ). ( )
// closure parameters for new control structures
given {} when {} then {}
( ). ( ). ( )
// zero‐arg methods require parens
select all unique() from names
// possible with an odd number of terms
take 3 cookies
36
81. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
( ). ( ). ( )
// leverage named‐args as punctuation
check that: margarita tastes good
( ). ( )
// closure parameters for new control structures
given {} when {} then {}
( ). ( ). ( )
// zero‐arg methods require parens
select all unique() from names
( ). . ( )
// possible with an odd number of terms
take 3 cookies
36
82. Command chains expressions
// methods with multiple arguments (commas)
take coffee with sugar, milk and liquor
( ). ( ). ( )
// leverage named‐args as punctuation
check that: margarita tastes good
( ). ( )
// closure parameters for new control structures
given {} when {} then {}
( ). ( ). ( )
// zero‐arg methods require parens
select all unique() from names
( ). . ( )
// possible with an odd number of terms
take 3 cookies
( ).
36
83. BigDecimal by default
• Main reason why financial institutions often decide
to use Groovy for their business rules!
– Although these days rounding issues are overrated!
37
84. BigDecimal by default
• Main reason why financial institutions often decide
to use Groovy for their business rules!
– Although these days rounding issues are overrated!
BigDecimal uMinusv = c.subtract(a);
BigDecimal vMinusl = b.subtract(c);
BigDecimal uMinusl = a.subtract(b);
return e.multiply(uMinusv)
.add(d.multiply(vMinusl))
.divide(uMinusl;
37
85. BigDecimal by default
• Main reason why financial institutions often decide
to use Groovy for their business rules!
– Although these days rounding issues are overrated!
BigDecimal uMinusv = c.subtract(a);
BigDecimal vMinusl = b.subtract(c);
BigDecimal uMinusl = a.subtract(b);
return e.multiply(uMinusv)
.add(d.multiply(vMinusl))
.divide(uMinusl;
(d * (b ‐ c) + e * (c ‐ a)) / (a ‐ b)
37
86. Custom control structures w/ closures
• When closures are last, they can be put “out” of the
parentheses surrounding parameter
unless (account.balance > 100.euros, {
account.debit 100.euros
})
38
87. Custom control structures w/ closures
• When closures are last, they can be put “out” of the
parentheses surrounding parameter
unless (account.balance > 100.euros, {
account.debit 100.euros
})
// calling the following method:
def unless(boolean b, Closure c)
38
88. Custom control structures w/ closures
• When closures are last, they can be put “out” of the
parentheses surrounding parameter
unless (account.balance > 100.euros) {
account.debit 100.euros
}
// calling the following method:
def unless(boolean b, Closure c)
38
89. Operator overloading
a + b // a.plus(b) • Currency amounts
a ‐ b // a.minus(b)
a * b // a.multiply(b) – 15.euros + 10.dollars
a / b // a.divide(b)
a % b // a.modulo(b) • Distance handling
a ** b // a.power(b) – 10.kilometers - 10.meters
a | b // a.or(b)
a & b // a.and(b) • Workflow, concurrency
a ^ b // a.xor(b)
a[b] // a.getAt(b) – taskA | taskB & taskC
a << b // a.leftShift(b)
a >> b // a.rightShift(b) • Credit an account
+a // a.unaryPlus() – account << 10.dollars
‐a // a.unaryMinus() account += 10.dollars
~a // a.bitwiseNegate() account.credit 10.dollars
39
92. Groovy’s MOP
• All the accesses to methods, properties, constructors,
operators, etc. can be intercepted thanks to the MOP
• While Java’s behavior is hard-wired
at compile-time in the class
• Groovy’s runtime behavior is adaptable
at runtime through the metaclass
• Different hooks for changing the runtime behavior
– GroovyObject, custom MetaClass implementation,
categories, ExpandoMetaClass
42
94. Hooks: ExpandoMetaClass
• A DSL for MetaClasses!
MoneyAmount.metaClass.constructor = { ... }
Number.metaClass.getDollars = { ... }
Distance.metaClass.toMeters = { ... }
Distance.metaClass.static.create = { ... }
• To avoid repetition of Type.metaClass, you can pass a
closure to metaClass { ... }
• The delegate variable in closure represents the current
instance, and it the default parameter
44
95. Adding properties to numbers
• Three possible approaches
– create a Category
• a category is a kind of decorator for default MCs
– create a custom MetaClass
• a full-blown MC class to implement
and to set on the POGO instance
– use ExpandoMetaClass
• friendlier DSL approach but with a catch
45
96. With a Category
class DistanceCategory {
static Distance getMeters(Integer self) {
new Distance(self, Unit.METERS)
}
}
use(DistanceCategory) {
100.meters
}
• Interesting scope: thread-bound & lexical
• Have to surround with “use”
– but there are ways to hide it
46
97. With an ExpandoMetaClass
Number.metaClass.getMeters = {‐>
new Distance(delegate, Unit.METERS)
}
100.meters
• But the catch is it’s really a global change,
so beware EMC enhancements collisions
47
104. Compile-time metaprogramming
• With metaprogramming, Groovy’s able to modify the
behaviour of programs... at runtime
• Groovy 1.6 introduced AST Transformations
– AST: Abstract Syntax Tree
– Ability to change what’s being compiled at compile-time!
• No runtime impact!
• Lets you change the semantics of your programs!
• Nice way of implementing patterns
and removing boiler-plate technical code
• Better interoperability with Java
– Jave code can call the methods / fields / etc injected in Groovy classes
52
105. AST Transformations
• Two kinds of transformations
– Global transformations
• applicable to all compilation units
– Local transformations
• applicable to marked program elements
• using specific marker annotations
53
106. AST Transformations
• Several (local) transformations available
– @ToString
– @Log
– @Delegate
– @Immutable
– and many more
54
107. @Immutable
• To properly implement immutable classes
– No mutators (state musn’t change)
– Private final fields
– Defensive copying of mutable components
– Proper equals() / hashCode() / toString() for
comparisons, or for keys in maps, etc.
@Immutable class Coordinates {
Double lat, lng
}
def c1 = new Coordinates(lat: 48.8, lng: 2.5)
def c2 = new Coordinates(48.8, 2.5)
assert c1 == c2
55
108. Global transformations
• Implement ASTTransformation
• Annotate the transfo specifying a compilation phase
@GroovyASTTransformation(phase = CompilePhase.CONVERSION)
class MyTransformation implements ASTTransformation {
void visit(ASTNode[] nodes, SourceUnit unit)
{ ... }
}
• For discovery, create the file META-INF/services/
org.codehaus.groovy.transform.ASTTransformation
• Add the fully qualified name of the class in that file
56
109. Local transformations
• Same approach as Globale transformations
• But you don’t need the META-INF file
• Instead create an annotation to specify on which element
the transformation should apply
@Retention(RetentionPolicy.SOURCE)
@Target([ElementType.METHOD])
@GroovyASTTransformationClass(["com.foo.MyTransformation"])
@interface CoolTransform {...}
57
110. Example: the Spock framework
• Changing the semantics of the original code
• But keeping a valid Groovy syntax
@Speck
class HelloSpock {
def "can you figure out what I'm up to?"() {
expect:
name.size() == size
where:
name | size
"Kirk" | 4
"Spock" | 5
"Scotty" | 6
}
}
• Check out http://www.spockframework.org
58
112. Various integration mechanisms
• Java 6’s javax.script.* APIs (aka JSR-223)
• Spring’s language namespace
• Groovy’s own mechanisms
• But a key idea is to externalize those DSL programs
– DSL programs can have their own lifecycle
– no need to redeploy an application because of a rule change
– business people won’t see the technical code
60
113. Java 6’s javax.script.* API
• Groovy provides an implementation of the javax.script.* API
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("Groovy");
String result = (String)engine.eval("2+3");
61
114. Spring’s lang namespace
• POGOs (Plain Old Groovy Objects) can be pre-compiled as
any POJO and used interchangeably with POJOs in a
Spring application
• But Groovy scripts & classes can be loaded at runtime
through the <lang:groovy/> namespace and tag
• Reloadable on change
• Customizable through a custom MetaClass
• <lang:groovy id="events"
script-source="classpath:dsl/bizRules.groovy"
customizer-ref="rulesCustomizerMetaClass" />
• More to come in the next version of Spring
62
115. Groovy’s own mechanisms
• GroovyShell, Eval, GroovyScriptEngine
– for more complex scripts and DSLs
• GroovyClassLoader or CompilationUnit
– the most powerful mechanisms
63
116. GroovyShell
• A Binding provides a context of execution
– can implement lazy evaluation if needed
• A base script class can be specified
– providing «global» methods and fields
def binding = new Binding()
binding.mass = 22.3
binding.velocity = 10.6
def shell = new GroovyShell(binding)
shell.evaluate("mass * velocity ** 2 / 2")
64
117. Imports customizer
• Inject imports in your scripts
– so that users don’t have to add imports manually
def configuration = new CompilerConfiguration()
def custo = new ImportCustomizer()
custo.addStaticStar(Math.name)
configuration.addCompilationCustomizers(custo)
def result = new GroovyShell(configuration)
.evaluate(" cos PI/3 ")
65
118. Applying an AST transformation
• Apply local AST transformations transparently
def configuration = new CompilerConfiguration()
configuration.addCompilationCustomizers(
new ASTTransformationCustomizer(Log))
new GroovyShell(configuration).evaluate("""
class Car {
Car() {
log.info 'Car constructed'
}
}
log.info 'Constructing a car'
def c = new Car()
""")
66
119. Externalize business rules
• Although Groovy DSLs can be embedded in normal Groovy
classes, you should externalize them
• Store them elsewhere
– in a database, an XML file, etc.
• Benefits
– Business rules are not entangled
in technical application code
– Business rules can have their own lifecycle, without requiring
application redeployments
67
120. Domain-Specific Language Descriptors
• DSLs are nice, but what about support in my IDE?
• DSLD to the rescue
– Domain-Specific Language Descriptors
– for Eclipse STS (but GDLS concent available in IntelliJ IDEA too)
• Idea: a DSL for describing DSLs, in order to provide
– code-completion
– code navigation
– documentation hovers
68
132. Example use case
• Biggest European travel services company
• Their customers
– travel agencies, airlines, booking websites...
• Customers want to customize the user experience
– use personalized forms and templates
– configure and tweak the underlying reservation features
• The company runs customers’ Groovy code
on their own platform and mutualised servers!
– How to secure that?
78
133. Sandboxing approaches
• Groovy supports the usual
Java Security Managers
– avoid System.exit(0)
• Use metaprogramming tricks to prevent calling or
instanciating certain classes
– think overriding constructors to throw exceptions
• Groovy 1.8 to the rescue
– compiler customizers
• SecureASTCustomizer
• ASTTransformCustomizer
79
134. Secure AST customizer
Idea: Implement an «arithmetic shell»
Being able control what a user script is
allowed to do: only arithmetic expressions
80
135. Secure AST customizer
Idea: Implement an «arithmetic shell»
Being able control what a user script is
allowed to do: only arithmetic expressions
• Let’s setup our environment
– some imports
– an import customizer to import java.lang.Math.*
– prepare a secure AST customizer
80
136. Secure AST customizer
Idea: Implement an «arithmetic shell»
Being able control what a user script is
allowed to do: only arithmetic expressions
• Let’s setup our environment
– some imports
– an import customizer to import java.lang.Math.*
– prepare a secure AST customizer
import org.codehaus.groovy.control.customizers.*
import org.codehaus.groovy.control.*
import static org.codehaus.groovy.syntax.Types.*
def imports = new ImportCustomizer().addStaticStars('java.lang.Math')
def secure = new SecureASTCustomizer()
80
138. Secure AST customizer
...
// language tokens allowed
tokensWhitelist = [
PLUS, MINUS, MULTIPLY, DIVIDE, MOD, POWER, PLUS_PLUS,
MINUS_MINUS, COMPARE_EQUAL, COMPARE_NOT_EQUAL,
COMPARE_LESS_THAN, COMPARE_LESS_THAN_EQUAL,
COMPARE_GREATER_THAN, COMPARE_GREATER_THAN_EQUAL
]
// types allowed to be used (including primitive types)
constantTypesClassesWhiteList = [
Integer, Float, Long, Double, BigDecimal,
Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE
]
// classes who are allowed to be receivers of method calls
receiversClassesWhiteList = [
Math, Integer, Float, Double, Long, BigDecimal ]
}
...
82
139. Secure AST customizer
• Ready to evaluate our arithmetic expressions!
...
def config = new CompilerConfiguration()
config.addCompilationCustomizers(imports, secure)
def shell = new GroovyShell(config)
shell.evaluate 'cos(PI/3)'
• But the following would have failed:
shell.evaluate 'System.exit(0)'
83
140. Test, test, test!
• Don’t just test for nominal cases
– Explicitely test for errors!
• Ensure end-users get meaninful error messages
84
142. Summary
• Groovy DSLs in the wild manage millions,
and even billions of Euros (one of my customers)
– so I guess we can say Groovy can be trusted :-)
• Groovy 1.8 adds some nice capabilities
for writing nicer plain-English-like business rules
• Tooling is improving greatly with DSL descriptors
– offering nice IDE integration for authoring business rules
86
143. Thank you!
e
aforg pment
ume L Develo
Guilla Groovy om
He ad of e@ gmail.c
glaforg rge
Email: @glafo
:
Twitter
87