« December 2011 | Main | February 2012 »
January 26, 2012
Podcatchers for Smartphones
As you might guess, given that I'm Executive Producer of IT Conversations, I like listening to podcasts. I'm also an iPhone user. Not to put too fine a point on it: iTunes sucks rocks for listening to podcasts. The problem is mostly that iTunes has a crappy interface for subscribing to and managing podcasts. It also downloads only one episode per day, with no way to change the defaults. Moreover it will stop downloading podcasts that you haven't listened to for a while and you have to remember to go in an start it up. I started feeling like I had to "take care of iTunes" like it was a recalcitrant pet or something.
For some reason, it never really occurred to me to download an app for listening to podcasts, although I've downloaded several single purpose ones (like the This American Life app). Then Paul Figgiani introduced me to Downcast. I'm in love. I no longer have to fight iTunes and all my favorites are right there waiting for me to listen to them when I go for a walk or drive to work. The interface is good, with plenty of controls for skipping forward and back or adjusting the playback speed. I also like the built-in "share" features although I wish they allowed me to customize the default text for the share.
Unfortunately, Downcast isn't available on Android. I have an Android tablet (Galaxy Tab) that I've used Google Listen on. It's a functional podcatcher, albeit a little bare-boned compared to Downcast: no speed or skipping controls and no built-in sharing.
So, go grab Downcast, plug in the IT Conversations feed URL and enjoy great tech talks from the longest running podcast on the planet...no matter where you're at.
9:20 PM | Comments () | Recommend This | Print This
January 20, 2012
My Letter to Senator Hatch in Opposition to PIPA
The Honorable Orrin Hatch
104 Hart Office Building
Washington, DC 20510
Fax: 202-224-6331
Dear Senator Hatch,
I'm writing to express my opposition to the Protect IP Act (PIPA). I have a PhD in Computer Science, have taught Computer Science at BYU, started several high-tech businesses in Utah (one of which, iMall.com, sold to Excite@Home in 1999 for $450 million), was the CIO for the State of Utah under Gov. Michael Levitt, and am the Precinct Vice-Chair in Lindon 04.
I'm pleased with Sen Reid's decision to postpone the vote and with your recent opposition to PIPA. However I'm still concerned that the thinking that led to PIPA will lead to other equally bad legislation in the future.
The problem with PIPA and similar legislation is that it looks at copying as a feature of digital goods that can be selectively disabled. In fact, everything I know about computer technology leads me to believe that copying will only get easier and easier as technology progresses. We will never again live in a time when copying things is as difficult as it is now. And this will be true regardless of the laws we pass because copying is fundamental to the nature of computers and digital goods.
Consequently, efforts to make copying more difficult by technical means (such as the DNS blocking provisions in PIPA and SOPA) hurt legitimate uses of technology while leaving those who would copy without permission plenty of ways to circumvent those measures. You cannot plug this hole by hobbling the Internet and also be a proponent of economic growth. Those positions are incompatible.
I believe that the answer lies in enforcing existing laws in the courts where the accused are afforded due process and in working with other nations to create legal regimes wherein the guilty can be tried and punished. There are no technical shortcuts that will solve this problem.
I'd be happy to discuss this matter in more detail. I look forward to seeing you at the convention.
Respectfully,
Phillip J. Windley, Ph.D.
Note: the paragraph about copying paraphrases Cory Doctorow's argument in his talk The Coming War on General Purpose Computing. I recommend listening to it.
8:42 AM | Comments () | Recommend This | Print This
January 14, 2012
Delivering Flowers with a Distributed Event System: Event Subscription in Action
This semester, I'm teaching a class at BYU, CS462. We're using Opher Etzion and Peter Niblett's book Event Processing in Action as the class text. The text uses a flower shop and delivery driver scenario as the running example throughout the book. Here's a description:
The flower stores in a large city have established an agreement with local independent van drivers to deliver flowers from the city's flower stores to their destinations. When a store gets a flower delivery order, it creates a request, which is broadcasted to relevant drivers within a certain distance from the store, with the time for pick up (typically now) and the required delivery time if it is an urgent delivery. A driver is then assigned and the customer is notified that a delivery has been scheduled. The driver picks up the delivery and delivers it, and then person receiving the flowers confirms the delivery time by signing for it on the driver's mobile device. The system maintains a ranking of each individual driver based on his or her ability to deliver flowers on time. Each store has a profile that can include a constraint on the ranking of its drivers, for example a store can require its driver to have a ranking greater than 10. the profile also indicates whether the store wants the system to assign drivers automatically, or whether it wants to receive several applications and then make its own choice.
The following diagram (from the Event Processing Technical Society's site) illustrates the interactions that take place between various entities:
The example that Opher details in the book has been implemented in several event processing systems.
If you follow my blog, you'll know I have a particular view of evented systems based on distributed event processing taking place on event networks that are owned and run on behalf of particular entities. We call these personal event networks. In addition to writing a book on the subject, I've described personal event networks in various articles on this blog over the last six months:
- Foursquare and Personal Data in a Personal Event Network
- Notifications in Personal Event Networks
- A Web of Things on the Internet of Things
- Products as Avatars for a Service
- Sky: The New Kynetx Event API
- The Second PC Revolution: Personal Clouds
- Human Leverage
- Personal Event Networks, Social Products, and Value
- What Personal Event Networks Do
- The Evented API Specification
- Personal Event Networks: Building the Internet of Things
- A Facebook of Things
- Curation in the Small: Personal Event Networks and Getting Things Done
- The Trends Driving KRL and Kynetx
- Anonymous eCommerce: Building a Real 4th Party Offer Application with Kynetx
- Contextually Correlating Events: The Power of Emergent Behavior in Loosely Coupled Systems
N.B. If you're in my CS462 class, it wouldn't hurt to read them all. :)
Consequently, as we implement the flowershop example in my class, we're going to do it with a personal event network twist. The result looks something like this diagram:
In the preceding diagram, there isn't one event system that manages the interactions between the shops and the drivers. Rather, each driver has their own personal event network, each shop has their own personal event network, and the guild has one too. The interactions aren't simply events raised within a single event network, but rather events raised between the networks of each participant. I've shown some of the apps that drivers, shops, and the guilds have installed on their personal event networks, but they would each be individually managed and configured. In fact, it's reasonable to assume that different drivers or shops might use different apps for the same purpose as long as they understood the events.
The various personal event networks are linked together via event subscription. For example, a driver might subscribe to the delivery_ready event from each of the flowershops she wants to drive for. A driver who has a bad experience with a particular shop, merely unsubscribes from that shop's delivery_ready events and never sees them again. Similarly, a shop that doesn't like a particular driver can merely unsubscribe from them and no longer do business with them. I'll be posting an example soon that shows how event subscription works in a personal event network. There are lots of details to work out and this blog post isn't the place for them.
There are design choices to be made in this system. For example, there's a "direct" arrow in the diagram indicating that shop and driver personal event networks can communicate directly. But the guild may chose to intermediate the interactions. In class, we're going to be implementing the system with a direct connection first and then re-plumb the entire thing to use the guild as an intermediary. Intermediaries introduce interesting dynamics, making many things easier and increasing flexibility.
Overall, this example isn't terribly different from the fourth-party ecommerce example I wrote about last June except that example featured hardwired connections between the shopper and the merchant rulesets. In contrast, this example uses the idea of event subscription to link merchants and customers. Event subscription takes the fourth-party example from a nice little demonstration to a conception of how VRM could work in the real-world. The diagram shown above can be partitioned to illustrate this:
Together with our ideas about how notification occurs and how personal data can be managed in personal event networks, event subscription creates a powerful system for enabling a completely new kind of interaction between vendors and customers (note that in this example, the flowershop is the customer who is negotiating for and buying delivery services from the drivers).
8:50 PM | Comments () | Recommend This | Print This
January 11, 2012
The Live Web is Live!
My book, The Live Web: Building Event-Based Connections in the Cloud, has been released and is on Amazon. Having the book actually available is great, although slightly anti-climatic after the thrill of just being done last November. :)
The book is my look at the future. When Eric Schmidt talks about a personalized house or we contemplate how commerce or health care will change in a completely connected world, that's the Live Web.
Buying the book: If you are going to order a copy from Amazon, do be a favor and order it on Friday, January 13th. I'm trying to get the book to move up the rankings--if only for a day.
Here's an excerpt from the Introduction:
For many years, pundits have foreseen a world in which everything will be connected to the Internet. We're getting there. We now have Wi-Fi--enabled refrigerators, thermostats, and bathroom scales. But what happens after things are online? Will they merely connect to the Internet or will they connect to each other?
Connecting everything we use--products and services--to each other is a powerful idea. An idea that is bigger than mobile and social. Mobile's big because everyone is connected all the time. Social is big because we're connected to each other. Connecting us to everything around us is the next step.
Connecting our things to each other and setting them to work on our behalf is transformative. Imagine a world in which your phone automatically mutes the ringer when you start watching a movie. Imagine a world in which your alarm clock sets itself based on your schedule and other information like the weather, the traffic, and your past behavior. Imagine a world in which the mundane parts of business travel or scheduling an appointment with a new doctor are automatically taken care of according to your preferences. That world is the Live Web.
The Live Web: Building Event-Based Connections in the Cloud is a book about specific concepts, architectures, and technologies you can use to build Live Web experiences. This book is not easy; it requires that you think about Web programming from a brand new perspective. That's hard for any of us. I have no business asking that of you unless there is a big payoff. There is: I believe the ideas and techniques in this book will help you build brand new types of Web experiences unlike those you can create using traditional Web technologies or languages like PHP or Rails. Don't let this intimidate you. While this book asks a lot, the ideas are familiar and their application is engaging and fun.
The premise of this book is simple, but profound: The Web of the future--the Live Web--will link our lives in ways we can hardly imagine..and you can start building that Web today. While the request-response programming model we've been using has led to incredible applications and services, we can do more with a new model that complements--rather than replaces--the thinking that has led us so far. That new model is based on events.
Whereas today's Web sites are about users interacting with relatively static pools of data, the cloud is giving us a brand new kind of data: data that is flowing, moving, and real-time. Data that links sites and services together. The cloud is about way more than just APIs to data and services--as important as that is. At its best, the cloud creates real-time interactions enabled by streams of data. The problem is that this kind of data doesn't look like a request. Consequently using the tried and tested tools we've used to build Web services won't take us where we need to go. Event-based interactions are the perfect model for taming these rivers of dynamic data and creating applications that make the most effective use of them.
Event-based applications are more loosely coupled than those built using a request-response model. I cannot overstate the case for loose coupling. As we move to a world in which more and more applications must coordinate their actions on our behalf, there is simply no way that we can pre-plan and orchestrate all the required interactions between them. Using systems that are supportive of and are architected for loosely coupled applications will play an important role in enabling the cloud-based future we envision.
This may seem a little overwhelming, but I have a secret weapon to help you out: a new programming language. I know what you're thinking, "Wait, I've got to think differently about the Web and learn a new language too!?!" But in fact, I think the language helps, rather than hurts.
Tools shape how we think and work. I learned long ago that the best way to think differently about a problem is to create a nomenclature that describes and illuminates the new domain. In this book, you'll use a language called the Kinetic Rules Language (KRL) to channel your thinking for this new model. KRL will lead you into the world of event-based programming on the Web.
KRL is a rule-based language that is custom built for the domain of event-based applications that operate on real-time data in the cloud. KRL was designed from the ground up with events and the cloud in mind. KRL provides a number of familiar touch-points for users already accustomed to Web programming and JavaScript, but provides a framework for making the most of an evented Web. While KRL is open and runs on an open source rules engine, you can get started with it right away using a cloud-based service.
While the ideas and techniques in this book can be implemented in any language, there is significant value in using a purpose-built language to guide our thinking. Remember, the ultimate value you will gain from this book isn't learning any specific programming language, but in forcing your thinking down a new road--one in which events, rather than requests, reign supreme.
I'm very pleased with how the book turned out and extremely excited about the ideas in it. I hope you'll read it, comment on it, review it, and try the ideas out. Undoubtedly, the future will turn out different than I've envisioned it, but I think we have an obligation to try to influence the design that emerges. The Live Web is my best thinking about how to do that.
Update: Some people have asked about a Kindle edition. There is a Kindle edition coming, but I don't know when it will be available.
8:30 PM | Comments () | Recommend This | Print This
January 6, 2012
Foursquare and Personal Data in a Personal Event Network
Lately I've been exploring APIs that push data and the use of personal data. While we're proponents of the Evented API specification, there are already a number of APIs that push data in some way. One of those is Foursquare.com. The Foursquare push API will call a URL anytime a user checks in. (Foursquare calls it the "real-time" API, but I'm coming to dislike that term as a description for this functionality.) They post data to a URL of your choosing. Turns out, with the Sky API accepts event signal URLs (ESLs) that meet the Evented API Specification and Foursquare can use properly formatted ESLs with their Push API. Consequently, Foursquare's Push API works perfectly with KRL.
Once I've checked in and Foursquare has pushed the checkin data to an ESL being watched by a KRL application, it's easy enough to store that data and then retrieve it from the same ruleset. KRL has identity built-in along with a concept of stateful variables that persist from invocation to invocation. These variables, called entity variables store data persistently on an entity-by-entity basis without any work on the developer's part.
But I wanted something more--a personal data store. I wanted the ruleset processing the checkin to see the Foursquare checkin event and put the data somewhere where other rulesets could use it. A KRL module with an associated rule turns out to be a good way to do this. The rule responds to a pds:new_location_available event and stores that data away. Other rulesets can access to the data using a function provided as a module. This ruleset just looks like any other application in my personal even network, seeing relevant events and doing it's job--but also functions as a KRL module for retrieving the data values.
The final result looks something like the diagram below.
Whenever I checkin at Foursquare, a foursquare:checkin event is raised to my personal event network. One of the apps, I've installed, the Foursquare Processor ruleset, is listening for events of that domain and type. The Foursquare Processor manipulates the data that Foursquare has sent and raises a pds:new_location_available event. Another app I've installed, the Personal Data Manager ruleset, is listening for that event and merely stores the Foursquare data away in an entity variable.
Later, I visit a Web page, exampley.com in this case, and a rule in another app I've installed, the PDS Inspector ruleset, retrieves the latest Foursquare checkin information from my Personal Data Manager using a function, get_location(), and displays it.
You can see these apps installed in my personal event network in the following screenshot. The apps that make this work are the ones in the red rectangle.
"Wait a minute!" I can hear you saying. "That's just the 'Manage Apps' page in your Kynetx browser extension!" Precisely. Installing an app in my Kynetx account is the same thing as installing it in my personal event network. My Kynetx account is showing me the apps that I've got installed in my personal event network and it's where I control how they behave. If you have a Kynetx account, you already have a personal event network.
A few points to make:
- None of these apps knows about the other ones. They are loosely coupled. None of them know what's going to happen when they raise their respective events because an event isn't a request. The behavior emerges from the particular suite of apps I have installed.
- This behavior isn't hard coded for me. These apps work generally across anyone's personal event network. Because these are stored in entity variables, if you install these apps in your personal event network, then you'll see your data, not mine. When you look at the code below, you won't see any code that makes that happen. That's because the personal event network infrastructure is handling all of the identity information below the ruleset level. KRL developers get multi-tenanted applications for free.
- Personal data is being managed by a separate ruleset allowing for indirection in how the data is used. Storing the checkin and seeing the checkin are asynchronous processes. Only apps I've installed in my personal event network can see the personal data in the Personal Data Manager. To see the data, apps have to use the Personal Data Manager module and thus disclose their intent to use personal data. This is not a final answer to a personal data store since it doesn't provide for explicit user permissioning, but it's getting a lot closer.
This demonstration shows a personal event network responding to Foursquare checkin events and storing the information about the checkin in a personal data service using a manager application that is loosely coupled and privacy respecting. Pretty cool, huh?
The Gory Details
What follows are the gory details of how it all works. Keep reading if you're into that sort of thing.
The Foursquare Real-Time API and KRL Events
Foursquare provides a method for creating an OAuth consumer. As part of that process, you'll need to register your application, providing the Web site URL and a callback URL. After you register the application, you need to edit it to provide a push URL. This is where you put the Sky API ESL:
https://cs.kobj.net/sky/event/<token>/fakeeid/foursquare/checkin
The token identifies the personal event network that the event is sent to. It's unique to the particular application raising the event. This creates a revokable, one-to-one connection between the Foursquare OAuth consumer and the personal event network. The token generator is still in beta; if you'd like to play with this, contact me and I'll tell you how to get to it. Here's what the Foursquare OAuth consumer page looks like when you're done:
You have to use OAuth to tie a Foursquare account to this Foursquare consumer. I just did it manually (cutting and pasting URLs into my browser) so that my Foursquare account was tied to this consumer. We're not quite using the Foursquare API the way they envisioned it. They think of a single OAuth consumer handling multiple accounts and thus a single push URL being used to push checkin data for every user who has authorized the OAuth consumer to see their acccount.
Instead, I'm tying the push URL (an ELS) to an OAuth consumer and then only tying a single user account to each OAuth consumer. This allows the Foursquare OAuth consumer to function as an endpoint for a single personal event network. The following diagram shows this difference.
I'd like to see Foursquare allow a user to associate a push URL directly with their account to save the trouble of creating serperate OAuth consumers and going through the OAuth process, but this works fine for now. The consumer detail page (shown above) contains a button for testing the push URL. You can do this before you go through the OAuth process. The biggest problem I had with it is that it didn't show the return value or response code and I was having a few problems debugging it, so that would have been helpful.
Once you've made these links, you have a Foursquare endpoint raising checkin events to your personal event network whenever you checkin with the Foursquare app on your smart phone:
The Foursquare Processor
The Foursquare processor is a KRL ruleset that is listening for foursquare:checkin events. The rule is selected when a foursquare:checkin event is raised. If you look cartefully at the event signal URL we gave to Foursquare that's shown above, you'll see that we've encoded that event domain (foursquare) and type (checkin) in the URL.
Here's the rule:
rule fs_checkin {
select when foursquare checkin
pre {
// decode the JSON to get the data structure
checkin = event:attr("checkin").decode();
}
noop();
fired {
raise pds event new_location_available with
key = "foursquare" and
value =
{"venue": checkin.pick("$..venue.name"),
"city": checkin.pick("$..location.city"),
"shout": checkin.pick("$..shout", true).head(),
"createdAt": checkin.pick("$..createdAt")
}
}
}
I'm picking apart the JSON structure that Foursquare sends and just looking at four values: the venue name, the city, the shout, and the checkin time. There's lots more data there, but this was sufficient for my purposes.
The rule's sole result is to raise another event, pds:new_location_available. Any other ruleset in the personal event network might be listening for this event. Note that this rule isn't controlling who will see the event or what they're supposed to do with it if they do see it. This is an example of semantic encapsulation that aids the loose coupling of personal event network applications.
The Personal Data Manager
The Personal Data Manager (PDM) ruleset is perhaps the most interesting of the three rulesets presented here because it's functioning as a ruleset to process event and a module for retrieving data. The PDM ruleset has a rule that is listening for the pds:new_location_available event that the Foursquare Processor ruleset raises.
rule add_location_item {
select when pds new_location_available
noop();
always {
set ent:location{event:attr("key")}
event:attr("value");
log "Saw " + event:attr("key") + " data";
raise pds event new_location_item_added
with key = event:attr("key");
}
}
This rule does three things when it sees a salient event:
- Stores the value of the event attribute named value in an entity variable named ent:location. Ent:location is a map and the key is taken from the event attribute named key.
- Writes a log message that it saw data with a given key.
- Raises a pds:new_location_item_added event.
The first is the primary result we want from this rule: the data gets stored in an entity variable. As I mentioned above, because this is an entity variable it will be persistently stored for the entity that owns the personal event network where this rule is running. In other words, the personal event network has a built-in method for storing personal data without the programmer ever having to worry about the identity and database issues involved in making it work.
The third result is interesting because it ensures that this rule is not a dead-end leaf on the event tree. In the case of this demonstration, there isn't any ruleset listening for the pds:new_location_item_added event in my personal event network; but there could be. Next week I might install an app that needs to know when my location changes and it will see this event and do whatever it does. Ensuring that there are no dead-ends is a good practice that aids loose coupling.
In addition to having a rule that responds to events and stores data, the PDM ruleset is also a KRL module:
meta {
name "Personal Data Manager"
provides get_item, get_location
}
global {
get_location = function (k) {
ent:location{k};
};
}
The module provides two functions: get_item() (not shown) and get_location(). Get_location() simply accesses and returns the value stored with a given key, k, in the location entity variable, ent:location.
Note that modules form a closure over persistent variables used in the ruleset because of the static scoping or persistent variables in modules. That means that when a rule stores something in a persistent variable in a module and a provided function retrieves it, they're talking about the same piece of data. This is the magic that allows a ruleset to act as a personal data manager.
The Personal Data Inspector
The Personal Data Inspector ruleset is simply a convinience for testing the system we've put in place and seeing that it all works. This app is a pretty standard KRL ruleset for modifying a Web page. The ruleset uses the PDM ruleset as a module so that it has access to the location data.
Here's the code for the entire ruleset:
ruleset a16x138 {
meta {
name "PDS Inspector"
use module a16x137 version "dev" alias pds
}
dispatch {
domain "exampley.com"
}
rule show_location_data {
select when pageview ".*"
pre {
fs_location = pds:get_location("foursquare");
v = fs_location.pick("$..venue");
c = fs_location.pick("$..city");
s = fs_location.pick("$..shout");
t = "Phil last seen at #{v} in #{c}";
body =
(s.typeof()) eq "str" => t + ' saying "#{s}"'
| t;
}
notify("Where's Phil?", body) with sticky = true;
}
The operation of the ruleset is simple:
- The ruleset uses the PDM ruleset (a16x137) aliasing it with the name pds.
- The dispatch section declares exampley.com as a salient domain so that the Kynetx Browser Extension (KBX) knows to run this ruleset on that domain.
- The rule uses the function pds:get_location() function from the PDM module with the key "foursquare" to get the data for the last checkin, picks it apart, and places a notification box on the Web page with the data about the last checkin.
With that, I see a notifcation box like this whenever I visit exampley.com:
This notification is happening aynchronously from the checkin data being stored. The Foursquare Processor ruleset stores the data whenever I check in. The PDS Inspector ruleset shows the last checking location whenever I visit this particular Web page. The PDM rule is sitting between then providing data storage for the shared data that these two rulesets use.
Conclusion
This demonstration has shown three primary ideas:
- Foursquare can be configured as an endpoint for a personal event network.
- A KRL ruleset can function as a data manager for personal data within the personal event network.
- A personal event network can function as an entity-specific event bus, allowing loosely coupled, semantically isolated applications to function together on an owner's behalf.
These ideas are each an important building block in creating the vision for personal event networks that function on behalf of their owners, protecting personal data and allowing applications to use shared personal data.
7:25 AM | Comments () | Recommend This | Print This
January 3, 2012
Static Scoping of Persistents in KRL Modules
With a title like that, I'm sure you just can't wait to dig into this blog post. The bottom line: I made a scoping mistake in designing modules and it's time for KRL to come clean about that. This post describes the problem and what's changing to fix it.
When I implemented KRL modules over a year ago, I was careful to ensure that module variables are statically scoped. For example, conside the following meta and global blocks from a KRL module:
meta {
provides b
}
global {
a = 5;
b = function(x) { x + a };
}
Now suppose this module gets used with the alias test like so:
global {
a = 16;
p = test:b(5);
}
Will p have the value 10 or 21? If module variables are statically scoped, it will have the value 10 because the variable reference a in the function bound to b will refer to the a in play when it was declared (static) rather than when it is run (dynamic). You've probably surmised that if variables are dynamically bound then p will have the value 21.
There's only one tiny problem: regular variables are not the only things that can be bound to values in KRL. KRL also has a special kind of variable called a persistent variable that holds it's value across invocations of the ruleset. When I implemented modules, I more or less ignored and forgot about persistents. The result was that they ended up being dynamically scoped. This causes confusion for developers because not only don't KRL modules that reference persistents behave the way that we've come to expect from other programming languages, but they don't behave consistent with module variables in KRL. The's poor language design and I'm sorry.
Here's a detailed look at what I mean. Supposed, we had the following ruleset:
ruleset foo {
meta {
provides get_item
}
global {
get_item = function (k) {
ent:elements{k};
};
}
rule add_item {
select when pds new_data_available
noop();
always {
set ent:elements{event:attr("key")} event:attr("value");
raise pds event new_item_added;
}
}
}
The provides declaration in the meta section clues us in that this ruleset is intended to be used as a module. Note that get_item() references an entity variable (ent:elements). An entity variable with the same name is mutated in the rule add_item. The idea is that this ruleset will function as a closure over the value in ent:elements allows the value to be set when the event pds:new_data_available is raised and retrieved via a function made available to other rulesets that use this one.
The problem is that persistent variables in modules are dynamically scoped whereas they're statically scoped when the ruleset is run because it contains a rule that responds to an event. Thus the two references to ent:elements in the preceding ruleset do not refer to the same place. The one in get_item() refers to the persistent ent:elements in the ruleset it runs in while the reference to ent:elements in the rule postlude refers to the persistent ent:elements in ruleset foo. That is clearly not what developers looking at this ruleset would expect and thus poor design.
In my defense, when I designed modules, I didn't even consider that some enterprising developer (yeah, I'm looking at you Sam Curren) would put rules in their modules. But they did and it proved to be very useful.
So, what we're going to do is fix this. We will make persisent variable references in modules statically scoped. If you're a Kynetx developer and you've written a module, you should ensure you haven't used persistents in module functions. If you have you're going to have to change your module to pass that value in as a function parameter, rather than simply referring to it. I doubt many people are relying on this, so we're just going to change it and help people fix their code later. Let me know if this is going to cause you too much heartburn.
1:40 PM | Comments () | Recommend This | Print This
January 2, 2012
Students Loans: Debt Peonage
Take a look at the following graph from the College Board's Trends site.

(click to enlarge)
What you'll notice is that the cost of attending a public 4-year college or unversity in 2011 was almost 4 times the cost in 1981--after adjusting for inflation. At the same time, state contributions to higher education also increased (albeit not by nearly as much).
The problem with the price increase is that it's difficult to undertand the increase in terms of the value of the product returned (a degree). We're essentially returning the same education for 4x the price.
As I struggle to understand this, I've hit upon a theory that it comes down to student loans. Student loans have made it much easier for students to borrow money. And when your chief customer has a lot more money, it's easier to charge them more for a given product. Outstanding student loans exceeded $1 trillion for the first time in 2011.
Many people think of student loans as "good debt" because they can lead to a higher paying job. But they are incredibly pernicious. They are easy to get, but difficult to discharge. And delayed payment terms while the student is in school make them especially attractive.
Taxpayers and other lenders have little risk of losing money on the loans, unlike mortgages made during the real estate bubble. Congress has given the lenders, the government included, broad collection powers, far greater than those of mortgage or credit card lenders. The debt can't be shed in bankruptcy.
The credit risk falls on young people who will start adult life deeper in debt, a burden that could place a drag on the economy in the future.
"Students who borrow too much end up delaying life-cycle events such as buying a car, buying a home, getting married (and) having children," says Mark Kantrowitz, publisher of FinAid.org.
From Student loans headed for $1 trillion this year -- USATODAY.com
Referenced Mon Jan 02 2012 16:15:54 GMT-0700 (MST)
This amounts to nothing less that debt peonage. Peonage is a system where debtors are forced to work for creditors in a kind of involuntary servitude.Thanks to Congress working closely to protect banks in the latest revision of bankruptcy laws, student loans are exempt from bankruptcy. Collections agencies can garnish wages, tax refunds, and even social security. Because there's no way to discharge the debt, student loans end up looking just like debt peonage.
As a consequence, students take out loans to pay for ever increasing college costs, struggle to repay them, and end up working for the creditor for a significant portion of their life. Granted many people do pay them back, but for many, the dream job doesn't work out and repayment is difficult.
Think back to the graph at the beginning of this post. We've created a system whereby a lot of money gets injected into system with less demand that the funds available. Consequently, prices went up. Universities control who is a student, the primary qualification for getting the money. Banks and universities benefit and students suffer. The purpose of the program--more educated people--never materializes.
I advise my kids to stay far away from student loans. I'd rather they take a semester or two off and work, if necessary, student loans are tantamount to debt peonage and I'd just a soon my children weren't enslaved for a good portion of their life. I can't help thinking that we've yet to see the real cost of this. I think it might make the housing bubble look like a warm-up act.


