Giter VIP home page Giter VIP logo

dog's Introduction

The Dog Programming Language

--------------------------------------------------------------------------

Developed by Salman Ahmad <[email protected]> 
and other contributors listed in the AUTHORS.txt file.

Licensed under the Apache License, Version 2.0. 
See COPYRIGHT.txt and LICENSE.txt for more details.

--------------------------------------------------------------------------

To build Dog locally with Maven:

	Build: mvn package
	Build without tests: mvn package -DskipTests=true 

	The output will be available under target/

To run:
	
	After building, execute src/bin/release/dog or
	src/bin/debug/dog.


dog's People

Contributors

salmanahmad avatar ef4 avatar ychen022 avatar vicli avatar rmahmad avatar sdkamvar avatar

Watchers

Ian McFarland avatar  avatar  avatar

dog's Issues

Mongo-Backed Sessions

Whenever a client connects to the API we ensure an associated session_id. The session_id is stored in Mongo as a document with the follow schema:

{
  session_id: <oid>,
  user_id: <oid>,
  last_activity: <date>
}

The session_id is associated with any data that is passed into a Dog program and developers can access this id. They can also associate a real user with the session.

The sessions will eventually timeout after some amount of times. Perhaps, 1 hour? They could also be implemented as a TTL collection in Mongo.

Installer

Create a proper installer for Dog that targets the appropriate platforms. Keep in mind that it may be easiest to redistributed the JVM.

Shell (REPL)

Revive the Dog REPL from the Ruby source tree.

POST /stream/:id is 500'ing out

track.continue is still being used on server.rb:413, presumably it needs to be replaced.

NoMethodError - undefined method `continue' for #<Dog::Track:0x007f8ac29ed708>

Should return null. Returns true

Code for fibonnaci.dog:

include dog

define fibonnaci: x_1 with: x_2 do

repeat 20 do
print: x_1
x_1 = x_1 + x_2
x_2=x_1-x_2

end

end

i = fibonnaci: 0 with: 1

print: i

OUTPUT

0.0
1.0
1.0
2.0
3.0
5.0
8.0
13.0
21.0
34.0
55.0
89.0
144.0
233.0
377.0
610.0
987.0
1597.0
2584.0
4181.0
true

*Note: When the print statement at the end is removed, the true disappears. *

In-Memory Mode

Allow Dog to run without the persistent mode enabled. This means that after the applications closes, all of the data is lost and while it is running it does not incur the MongoDB overhead (200mb database initialization, disk I/O, etc.).

This could actually be useful for many utility scripts that will be needed in the Dog source tree. The more things written in Dog, the better.

Suppress empty file parse error

Right now when you attempt to dog compile an empty file it gives an error saying the file is empty. I think this should be a warning and allow other files to still be compiled.

NOT operator in predicates

When implementing predicates (see Issue #35) I intentionally left out the unary not operator because there was no straight forward and natural way to negate a MongoDB query expression. I attempted to implement a syntax transformer that walked the query and switched the operators ($gte becomes $lt, etc.) but it did not seem to work well with $elemMatch.

I still think that it may be possible but it is a lot of work for something that may not get much use so I am tabling it for now and we can come back to it later.

[API branch] Fetch correct 'items' for /stream/track

In server.rb, we have the line:362

items = ::Dog::StreamObject.find({"track_id" => track.id})

to fetch the correct notifys and asks for a given track when it is GETed.

Unfortunately, this doesn't seem to be working, as currently the items is being populated with items from the parent scope.
This is after I get a success: true for creating a resource.

In the Twitter example, after creating a tweet, I get the listen in items for GETing a particular track listed in the listen's items.

Yeah, it's circular. And complicated.

Socket-Based Client API

Update the API to be socket based. The new API will have the following end points:

GET dog/task/<id>
POST dog/task/<id>/<channel>
SOCKET dog/task/subscribe/<id>

When a viewport renders a template for a task, the client libraries will auto subscribe for changes to the task.

When the client sends a listen the API will "queue" up the listen invocation but then return immediately. The runtime executes on another "thread" from the API server.

Whenever changes are made to the task, a "ping" is sent to all clients subscribed to the task's channel.

Whenever the client receives a "ping" over the socket, it will reload (pull) the task and update any "viewports" that are rendering a template for the task.

Viewports render templates for a task. Whenever a task changes, the viewport will auto-reload the task. Viewports' task can be hardcoded, for example, many applications will have a viewport that will always load the "root" task, but they can also be set programmatically and reloaded(). When a viewport sends a listen to the server, and there are updates to that task, the entire viewport is replace with the new template. This is true for both on and on each waits.

There is also a nested {{viewport}} helper that will allow nested templates for tasks that are displayed to the clients.

Optional args

DEFINE rank_k_teachers FOR shell ON me, teachers USING k = 5 DO
  PERFORM "python ranking.py"
  RETURN teachers_list
END

Throws an error at compile time.
Not urgent.

Exception Handling

General syntax:

do
  throw 3.14159 # Can throw any value.
catch error
  // Only one catch block. If you want to dispatch based on the type of the exception, implement it yourself.

  throw // Throw without a value will re-throw the current exception
ensure
  // Always runs  
end

The catch and ensure can be attached to any do block, even the blocks that represent control structures and functions:

define returns_pi do
  throw 3.14159
catch error
  i = error
ensure
  return i
end

In terms of implementation, the Signal class should be augmented to have an error field that will get propagated up until it is caught.

Standard API: Check if user is logged in

Add an API method that will check if a user object represents a user that is registered with the system or not. In other words, have an API method that indicates if the user is an anonymous user or not.

Nil exception after Listen returns

Code:

DEFINE view_homepage FOR user DO

    LISTEN TO user FOR goals
    LISTEN TO user FOR logins

    ON goal DO
        ASK user TO create_account
    ELSE ON login DO
        PRINT "LOGIN"
        #ASK user TO login
    END
END

Crash follows after "PRINT 'LOGIN'"

NoMethodError - undefined method _id' for nil:NilClass: /Users/samanthaainsley/dog/lib/dog/runtime/server.rb:347:inblock in initialize'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:1211:in call' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:1211:inblock in compile!'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:785:in []' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:785:inblock (3 levels) in route!'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:801:in route_eval' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:785:inblock (2 levels) in route!'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:822:in block in process_route' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:820:incatch'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:820:in process_route' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:784:inblock in route!'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:783:in each' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:783:inroute!'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:886:in dispatch!' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:719:inblock in call!'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:871:in block in invoke' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:871:incatch'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:871:in invoke' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:719:incall!'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:705:in call' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/rack-1.4.1/lib/rack/session/abstract/id.rb:205:incontext'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/rack-1.4.1/lib/rack/session/abstract/id.rb:200:in call' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/rack-protection-1.2.0/lib/rack/protection/xss_header.rb:22:incall'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/rack-protection-1.2.0/lib/rack/protection/path_traversal.rb:16:in call' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/rack-protection-1.2.0/lib/rack/protection/json_csrf.rb:17:incall'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/rack-protection-1.2.0/lib/rack/protection/base.rb:47:in call' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/rack-protection-1.2.0/lib/rack/protection/xss_header.rb:22:incall'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/rack-1.4.1/lib/rack/logger.rb:15:in call' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/rack-1.4.1/lib/rack/head.rb:9:incall'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/showexceptions.rb:21:in call' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:1334:inblock in call'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:1416:in synchronize' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/sinatra-1.3.2/lib/sinatra/base.rb:1334:incall'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.4.1/lib/thin/connection.rb:80:in block in pre_process' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.4.1/lib/thin/connection.rb:78:incatch'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.4.1/lib/thin/connection.rb:78:in pre_process' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.4.1/lib/thin/connection.rb:53:inprocess'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.4.1/lib/thin/connection.rb:38:in receive_data' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:inrun_machine'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in run' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.4.1/lib/thin/backends/base.rb:63:instart'
/Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.4.1/lib/thin/server.rb:159:in start' /Users/samanthaainsley/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.4.1/lib/thin/server.rb:145:instart'
/Users/samanthaainsley/dog/lib/dog/runtime/server.rb:399:in run' /Users/samanthaainsley/dog/lib/dog/runtime.rb:311:instart_stop_server'
/Users/samanthaainsley/dog/lib/dog/runtime.rb:119:in run' /Users/samanthaainsley/dog/lib/dog/runtime.rb:85:inrun_file'
/Users/samanthaainsley/dog/bin/dog.rb:343:in run' /Users/samanthaainsley/dog/bin/dog.rb:68:inrun'
/Users/samanthaainsley/dog/bin/dog.rb:42:in run' /Users/samanthaainsley/dog/bin/dog.rb:607:in

'

Add oneach to /stream

Needs to be a part of stream to register listeners for new tracks.
Cleans up API links between ASK, LISTEN and ON EACH.

In Twitter example, this means not having to defer listening for new tweets till LISTEN is used.

`name` attribute for items in API

It would be great to make this match the Dog code.
So we want it to be pluralized, and we also want to use the array to indicate hierarchy, though the latter is low-pri.

So

LISTEN FOR tweets

would turn into

{
  name: [ 'tweets' ]
  ...
}

Incidentally, this also works great with hard to pluralize items like

LISTEN FOR octopii OF octopus

LISTEN TO null

There is weird behavior when you LISTEN TO null FOR my_variable. Explore this at some point.

Cluster Mode

Update the scheduler to work better with distributed workloads. Right now the scheduler spawns threads to deal with concurrency. The runtime should have a configuration capability to set a maximum number of system threads. When the runtime exceeds that limit it queues the thread so any "node" in a cluster can schedule it.

This features would require adding an atomic "scheduled" or "pending" state to the StackFrame class.

Implementing the distributed worker queue may be a perfect fit for Mongo's capped collections.

This also includes seemingly simple enhancements including:

  • Command line options for customizing the API port
  • Command line options for customizing the Mongo port

Improper class names being produced

Compiling this code:

package package

define foo: bar do
    dog.print: bar
end

dog.print: "Hello!"

Creates a .class files that seems wrong: [package]$dot$foo$colon$.class

Function Resolution with Packages

This code fails and it probably shouldn't:


package my_package
include dog

define adder: arg do
    return 5 + arg
end

i = adder: "hello!"

print: i

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.